Static Site Generator with Strapi 4 and Jekyll
So I guess you heard about Headless CMS?
If you are not familiar with the concept — there is a handy Wikipedia page https://en.wikipedia.org/wiki/Headless_content_management_system. To read about Static Site Generators I do recommend Cloudflare article: https://www.cloudflare.com/en-gb/learning/performance/static-site-generator/.
In this article I am going to describe how to use Jekyll as Static Site Generator using Strapi version 4 as Headless CMS backend.
Requirements
To perform exercises described in this article you are going need following:
- Ruby https://www.ruby-lang.org/en/documentation/installation/
- Jekyll https://jekyllrb.com/docs/installation/
- NodeJS and npm https://docs.npmjs.com/downloading-and-installing-node-js-and-npm
- Python3 (but you can use any other http server)
Current state of jekyll-strapi plugin
Whatever you are working on — a blog, a portfolio or a landing page — Strapi and Jekyll seems be a good duo to help you deliver your solution. There is a Jekyll plugin: https://github.com/strapi/jekyll-strapi/ which allows to use Strapi as source for Jekyll’s Collections. However, there are some little issues with it:
- It does not support authentication
- It does not work well with media files
- It does not work with the new Strapi version 4
- It is not maintained anymore (there is a discussion in Strapi community about the future of this and another repos, however for today the topic is still not solved)
During last few months there were few contributions of volunteers to make plugin compatible with Strapi version 4. Unfortunately, none of them have been merge — on one side there was not maintainer of the repo, on the second — pull requests seemed a bit incomplete for me.
This sounded for me like a good challenge, so I refreshed a bit of my knowledge of Ruby, and after around one week I had plugin not only working with Strapi 4, but also adding some missing features like authentication, unit tests and proxy filters.
Simple portfolio website
In this example, we are creating a very simple Photography portfolio page, where users can upload a photo with a title and a simple description.
Strapi Configuration — CMS Setup
Create a new Strapi project:
npx create-strapi-app@latest my-project-photo --quickstart
And then to start the project:
cd my-project-photo
npm run develop
Or if you are using yarn:
yarn create-strapi-app@latest my-project-photo --quickstart
cd my-project-photo
yarn run develop
Now you should have a reachable Strapi instance here: http://localhost:1337/.
Strapi Configuration — Collection setup
Go to Content-Type Build in your admin instance http://localhost:1337/admin/plugins/content-type-builder/ and then create Collection as below:
To create the fields choose:
Text field for the Title, type of Short text:
Media field with a name Image, type Single media:
Text field with a name Comment, type Long text:
Finally, you should have something similar to:
Now go to Content Manager and add your first object to the database:
Auth token generation
Go to: http://localhost:1337/admin/settings/api-tokens/create and create a new token:
After the creation — save the token aside — you will need it later. Some password manager is recommended.
Plugin installation
In your Jekyll project add to Gemfile:
gem “jekyll-strapi-4”, “~> 1.0.11”
and install bundle:
bundle install
Jekyll project configuration
Add jekyll-strapi-4 to the plugins in _config.yml:
plugins:
- jekyll-feed
- jekyll-strapi-4
and following at the end of _config.yml:
strapi:
# Your API endpoint (optional, default to http://localhost:1337)
endpoint: http://localhost:1337
# Collections, key is used to access in the strapi.collections
# template variable
collections:
# Example for a "Photo" collection
photos:
# Collection name (optional)
# type: photos
# Permalink used to generate the output files (eg. /articles/:id).
permalink: /photos/:id/
# Layout file for this collection
layout: photo.html
# Generate output files or not (default: false)
output: true
We install the plugin:
gem install $MAIN_PATH/jekyll-strapi/jekyll-strapi-0.4.1.pre.dev.gem
rm Gemfile.lock
bundle install
Edited 2022–07–21: I have created a GitHub packages https://github.com/bluszcz/jekyll-strapi/packages/1554094 which can help you to install the necessary gem.
Then in _layouts
directory create two files, home.html
:
---
layout: default
---
<div class="home">
<h1 class="page-heading">Photos</h1>
{%- if strapi.collections.photos.size > 0 -%}
<ul>
{%- for photo in strapi.collections.photos -%}
<li>
<a href="{{ photo.url }}">{{ photo.strapi_attributes.Titlle }}</a>
</li>
{%- endfor -%}
</ul>
{%- endif -%}
</div>
and photo.html:
---
layout: default
---
<div class="home">
<h1 class="page-heading">{{ page.strapi_attributes.TestDescription }}</h1>
<h2>{{ page.document.strapi_attributes.Title }}</h2>
<p>{{ page.document.strapi_attributes.Comment }}</p>
<img src="{{ page.document.strapi_attributes.Image.data.attributes.formats.thumbnail| asset_url }}"/>
</div>
Now you must set the environmental variable with auth token (you need to use the previously saved token here):
export STRAPI_TOKEN=328438953489534...345423053895
and now you can generate your page:
bundle exec jekyll build --trace
And after that you can check your website:
cd _site
python3 -m http.server
and opening http://localhost:8000 in your browser.
Deployed example — demo
Here you can see the page from the previous example deployed to GitHub pages: https://jekyll-strapi-v4-example.bluszcz.net/
It is using the following GitHub repository: https://github.com/bluszcz/jekyll-strapi-v4-example.github.io/