Building a static blog using Jekyll and Strapi

Jekyll Strapi

A static website contains Web pages with fixed content. Technically, it is a simple list of HTML files, which displays the same information to every visitor. Unlike dynamic websites, they do not require any back-end programming or database. Publishing a static website is easy: the files are uploaded on a simple Web server or storage provider. The two main advantages of static websites are security and speed: there is no database so it can not be hacked and there is no need to render a page for each request, which makes Web browsing faster.

To make their creation easier, numerous open-source static websites generators are available: Jekyll, Hugo, Gatsby, Hexo, etc. Most of the time, the content is managed through static (ideally Markdown) files or a Content API. Then, the generator requests the content, injects it in templates defined by the developer and generates a bunch of HTML files.

In this tutorial, you are going to learn how to build a blog with Jekyll. A static website needs a source of content: in this example we will deliver it using an API created with Strapi.

Note: the code source of this tutorial is available on GitHub.

What is Jekyll?

With more than 34,000 stars on GitHub, Jekyll is definitely the most famous static website generator.

Jekyll logo

Developed on top of Ruby, Jekyll makes static website creation super easy. It includes many features such as permalinks, categories, pages, and custom layouts. Write some Markdown files, customise your templates and you will get an easy to host website in seconds.

Last but not least, Jekyll is the static website generator powering GitHub Pages!

What is Strapi?

Strapi is the most advanced Node.js API Content Management Framework. Halfway between a Node.js Framework and a Headless CMS, it saves weeks of API development time.

Thanks to its extensible plugin system, it provides a large set of built-in features: Admin Panel, Authentication & Permissions management, Content Management, API Generator, etc.

Unlike online CMSs, Strapi is 100% open-source (take a look at the GitHub repository), which means:

  • Strapi is completely free.
  • You can host it on your own servers, so you own the data.
  • It is entirely customisable and extensible, thanks to the plugin system.

API Setup

To make the magic happen, let's create a Strapi API and add some content.

Create a Strapi project

Install Strapi

Requirements: please make sure Node 9 and MongoDB are installed and running on your machine.

Install Strapi using npm:

$ npm i strapi@alpha -g

Note: Strapi v3 is still an alpha version, but it will be fine for this tutorial.

Generate a Strapi project

Create a directory named jekyll-strapi-tutorial:

$ mkdir jekyll-strapi-tutorial

Scaffold your API inside it through a single command line:

$ cd jekyll-strapi-tutorial
$ strapi new api

The CLI will ask you to choose your database: select MongoDB (currently better supported). Then, fill the database information. The default values should work if you correctly installed MongoDB.

Strapi setup

Start the server

Enter inside your project's folder:

$ cd api

Launch the Node.js server:

$ strapi start

Strapi start

Starting now, you should be able to visit the admin panel of your project: http://localhost:1337/admin.

Create your first User

Add your first user from the registration page.

Strapi register

Create a Content Type

Strapi APIs are based on a data structure called Content Types (equivalent of models in frameworks and Content Types in Wordpress).

Strapi Content Type Builder

Create a Content Type named post with five fields:

  • title with type string.
  • slug with type string.
  • content with type text, select the WYSIWYG in the advanced options section.
  • cover with type media.
  • author with type relation: many posts related to one user.

Tutorial

Insert some entries

Add some posts in the database. To do so:

  1. Visit the posts list page.
  2. Click on Add New Post.
  3. Insert values (please make the sure the slug contains only url safe characters), link to an author and submit the form.
  4. Create one or two other posts.

Strapi Content Manager

Allow access

For security reasons, the API access is, by default, restricted. To allow access, visit the Auth and Permissions section for Guest role, select the Post - find action and save. At this point, you should be able to request the list of posts.

The author API access is also restricted. Authorize anonymous access by selecting the find (in "Users & Permissions" section) action and saving the form.

Strapi Users & Permissions

Static website development

Great job, your API is ready! We can start developing the static website.

Install Jekyll

Requirements:

  • Ruby version 2.2.5 or above, including all development headers (ruby installation can be checked by running ruby -v)
  • RubyGems (which you can check by running gem -v)
  • GCC and Make (in case your system doesn’t have them installed, which you can check by running gcc -v,g++ -v and make -v in your system’s command line interface)

First, install the Jekyll CLI:

$ gem install jekyll bundler

If you have any issue installing Jekyll, please take a look at the Jekyll's documentation or at this issue.

Generate a Jekyll project

In the folder jekyll-strapi-tutorial that you previously created, generate your brand new blog:

$ jekyll new blog

Jekyll generate project

Start in development mode

Enter in your project's folder:

$ cd blog

Start the server:

$ bundle exec jekyll serve

Jekyll start server

At this point, you should able to see your fresh blog at http://localhost:4000.

Jekyll home page

Install the jekyll-strapi plugin

When you manage a static website, your data can come from different sources: Markdown files, CSV files, a WordPress website (using the JSON REST API plugin), etc.

By default, Jekyll uses Markdown files to manage data. Fortunately, thanks to the plugin system, you can get data from any source.

To connect Jekyll to a new source of data, you have to develop a new plugin. Several plugins already exist, so one of them should fill your needs.

In this example, we are using Strapi. Obviously, we are going to need a plugin compatible with Strapi APIs. Good news: we built it for you!

Add the jekyll-strapi gem to your Gemfile:

Install the gem:

gem install jekyll-strapi  

Then add jekyll-strapi to your plugins list in _config.yml:

Finally, run:

$ bundle install

This plugin need some configurations. Add the end of _config.yml, add the following content:

Posts list

First, we want to display the list of articles. To do so, we are going to instruct Jekyll to retrieve the list of posts:

Each Content Type must be listed in the collections object. The type field is used to build the URL requested. For example, if your type is product, the requested URL will be http://localhost:1337/product. The permalink is the URL structure you want to use for your blog posts. We could have chosen /posts/:id, but slugs are more friendly.

After that, we need to display the data. Jekyll uses a theme system. By default, the used theme is minima. The theme's files are not generated in the Jekyll projects, but you can override every theme's template by creating a file with the same name in the _layouts folder. To replace the existing home page content, create the folder _layouts with home.html inside it:

Finally, restart the server (ctrl + c and $ bundle exec jekyll serve) to let Jekyll consider these updates and admire your list of articles at http://localhost:4000.

Explanations

At the top of the file, we indicate the layout we want to use in order to display the header and the footer.

The plugin jekyll-strapi exposes the data received from the API through the global variable strapi, which is accessible from every template. To display the list of posts, we checked that the list strapi.collections.posts is not empty. If it is the case, we loop on it to display each item.

As you can see, some fields are displayed using |. The vertical line symbol is used by Jekyll's filters, which alter the way to display text. For example, post.createdAt uses the data_to_string to display the post's creation date in a more human friendly way.

Every entry includes an additional property named url which represents the url of the record's page based on the permalink given in the configuration.

Articles list

Post view

Our website now starts looking like a blog which is a good thing. However, an important part is still missing: the post’s details page.

Let's create the template and define the content displayed in a new file named post.html located in the _layouts directory:

The template displays the title of post, some meta data and convert the content from Markdown to HTML.

In _config.yml we must add layout and output lines to indicate to Jekyll that we want to generate a new page for each post, using the template we previously created.

After restarting the Jekyll server, you should be able to see a new folder named posts, in the _site folder, containing the generated pages.

From now on, you can visit the detail page by clicking on URLs displayed on the homepage.

Article page

Author view

Articles are written by authors. They deserve a dedicated page.

The processes for creating author views and article pages are very similar. First, we create the template:

Let's add the the new collection in the config file:

Path: _config.yml

Finally, restart the server and visit the author page from the article view's links.

Author page

Conclusion

Congrats! You’ve successfully built a super fast and easy-to-maintain blog!

Since the content is managed by Strapi, the authors can write post through a nice UI and developers only have to rebuilt the Jekyll blog in order to update the content.

Where to go next?

Feel free to continue this project to discover both Jekyll and Strapi advantages. Here are some features you can add: list of authors, post's categories, and comment system with the Strapi API or Disqus. You can also create other kind of websites (e-commerce shop, corporate website, etc.).

When your project is achieved, you will probably want to deploy it. The static website generated by Jekyll can easily be published on storage providers: Netlify, S3/Cloudfront, GitHub pages, GitLab pages, Heroku, etc. The Strapi API is nothing else than a simple Node.js API, so it can be hosted on Heroku or any Linux instance that has Node.js installed.

The code source of this tutorial is available on GitHub.

We hope you enjoyed this tutorial. Feel free to comment on it, share it, and let us know how you create static sites and manage their content.