Skip to content

Instantly share code, notes, and snippets.

@MichaelCurrin
Last active December 2, 2024 08:30
Show Gist options
  • Save MichaelCurrin/7e75f6c04d1cd14f2c6583f9fad1d218 to your computer and use it in GitHub Desktop.
Save MichaelCurrin/7e75f6c04d1cd14f2c6583f9fad1d218 to your computer and use it in GitHub Desktop.
Render content for all Jekyll pages as a single JSON endpoint

Make a REST API with Jekyll

Render content for all your Jekyll pages as a single JSON endpoint

Usecase

You have the content of your site stored as Markdown pages, but you want to load each page as structured data. Such as for building a SPA (with React or Vue) or a mobile app.

How it works

The JSON Liquid file below uses all pages in the site and renders their content as one file.

The output has key-value pairs, with the page's URL as the key and and the content as plain text (no markdown or HMTL) for the value.

{
 "PAGE_URL": "PAGE_CONTENT"
}

See sample-data.json below for a more realistic version.

There is a where expression to only include HTML and Markdown pages that are useful. This will filter out pages like feed.xml, robots.txt, sitemap.xml and CSS. As well as the JSON API file itself.

Set up

  1. Copy the content of the JSON file below. (The .liquid extension is for syntax highlighting as a gist, but just think of it as a .json file.)
  2. Add to your project as JSON file e.g. data.json in your project root. Or api/data.json.
  3. Start your Jekyll server.
  4. View the page where your JSON file is served from e.g. http://localhost:4000/data.json

Notes

  • Rather than outputting key-value pairs, another approach would be building an array of pages, where each item has the structure: { "url": "", "content": ""}.
  • jsonify is used here to add double quotes around a string, not to actually render an array or hash as a JSON object. Using jsonify is safer than manual quotes, as it will handle escaping quotes for you.
  • We use markdownify to convert markdown to HTML, then strip HTML to convert to plain text.
  • Unfortunately, we can't use Jekyll filters to process Liquid tags {{ }} or {% %}. So your content will not look so readable if you render it on a webpage. But a custom Jekyll plugin in Ruby could be used to evaluate that before the content is outputted to the JSON file.
  • See Jekyll cheatsheet
  • The sample JSON file below shows output based on running this site locally - MichaelCurrin/jekyll-blog-demo. It's pages are index.md, about.md and 404.html.
---
---
{%- assign pages = site.pages | where_exp: "p", "p.layout != nil" -%}
{
{%- for p in pages %}
{{ p.url | jsonify }}: {{ p.content | markdownify | strip_html | jsonify }}
{%- unless forloop.last %},{% endunless -%}
{% endfor %}
}
{
"/404.html" : "\n\n\n 404\n\n Page not found :(\n The requested page could not be found.\n\n",
"/about/" : "This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at jekyllrb.com\n\nSource code:\n\n\n\n\n",
"/" : "\n\nWelcome to my Jekyll Blog Demo\n\n\n {{ site.description }}\n\n\n\n\n\n\n\n \n \n \n\n"
}
@iparr
Copy link

iparr commented Nov 26, 2024

I just used this for a Jekyll migration. Nice one, Michael.

@MichaelCurrin
Copy link
Author

You're welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment