Managing Jekyll posts in Notion

2022-03-24 6 min

Editing posts in markdown is a convenient way to separate the content from the view. Jekyll and other tools like Hugo or Gatsby offer this way of creating and editing content. But it is not very practical to rely on the source code to edit them. It is also for non-technical users not easy to edit markdown in the codebase.

Personally, I prefer to use notion for this matter. Notion not only allows for a smooth writing experience but it is also portable. Just by having an internet connection, I can write wherever I am with my laptop or cell phone.

Anyone would think that notion pays me. But it doesn’t. It is simply one of the tools I use the most.

For a while, I was thinking about the idea of connecting Notion and Jekyll. I found it quite cumbersome to have to export from Notion, adapt to markdown and then upload the changes to the repository. I finally came up with the idea of jekyll-notion.

And now, once I think a blog post is finished, all I have to do is build the Jekyll project and deploy the website without having to access the source code and upload the changes to the repository. The build and deployment can also be automated, but that’s a topic for another post.

So, let’s cut with the blah, blah, blah and see how to manage Jekyll posts in Notion.

Set up

The first thing to do is to create a Notion database. A database can be of any type proposed by Notion. Usually, I feel more comfortable handling posts (or any other collection) with a table view.

What we can do is to create a page and add an inline table called Posts. In fact, everything related to my website is kept on the same page. It looks like this.

What’s cool about notion databases is that we can have more than one view, each view can contain different filtering and sorting based on the properties of the items it contains.

For the Posts database, I have created two views: WIP and Published. The Published view looks as follows.

The only difference between both views is the filtering rule applied based on the done property. Checked for published, unchecked for WIP. Once a post is finished, I just have to mark the done checkbox.

To try it out, I’ll leave you a few minutes to configure the database to your liking and come back when you’re done.

By the way, don’t forget to share the database with your Notion integration before proceeding with Jekyll.

Now that your database is ready and shared with some published articles, let’s configure jekyll-notion.

Open the _config.yml file and set the database id as follows.

notion:
  databases:
		- id: 3471f31x073a43f29487f84e16618ax93

By default, a database maps to Jekyll’s posts collection, so there’s no need to configure it.

Type jekyll serve in your console and you should see a similar output.

...
      Generating...
      Remote Theme: Using theme emoriarty/jekyll-theme-notion
     Jekyll Notion: Page => Load notion pages in jekyll
                    URL => /dev/2022/03/20/load-notion-pages-in-jekyll/
     Jekyll Notion: Page => jekyll-notion
                    URL => /dev/2022/03/19/jekyll-notion/
     Jekyll Notion: Page => The story of React
                    URL => /dev/2022/03/14/the-story-of-react/
       Jekyll Feed: Generating feed for posts
...
    Server address: http://127.0.0.1:4000
  Server running... press ctrl-c to stop.

Yes, all your posts are now in Jekyll. Try visiting any of the posts you see in your console.

Layout and front matter

Probably, if we do not set a layout, the posts will not look good. We can set the layout for all posts using front matter defaults.

defaults:
  -
    scope:
      path: ""
      type: posts
    values:
      layout: post

We can also set the layout property in notion in each post but it is more appropriate to use the Jekyll defaults. In fact, almost any property added in notion will be available in the front matter. Check here the exceptions.

Notice that the date of a post is the creation date assigned automatically by Notion. As far as I know, Notion does not allow to modify it. But if we want to change it, what we can do is duplicate the page in the database and delete the old one. That will generate a new creation date.

To find out which properties are available per page, we run Jekyll in verbose mode.

$ jekyll build --verbose
...      
      Reading: _posts/2022-03-20-load-notion-pages-in-jekyll.md
Jekyll Notion: Page => Load notion pages in jekyll
               URL => /dev/2022/03/20/load-notion-pages-in-jekyll/
               Props => ["draft", "categories", "layout", "nav", "done", "tags", "id", "title", "created_time", "cover", "icon", "last_edited_time", "archived", "date", "slug", "ext", "excerpt"]
      Reading: _posts/2022-03-19-jekyll-notion.md
Jekyll Notion: Page => jekyll-notion
               URL => /dev/2022/03/19/jekyll-notion/
               Props => ["draft", "categories", "layout", "nav", "done", "tags", "id", "title", "created_time", "cover", "icon", "last_edited_time", "archived", "date", "slug", "ext", "excerpt"]
      Reading: _posts/2022-03-14-the-story-of-react.md
Jekyll Notion: Page => The story of React
               URL => /dev/2022/03/14/the-story-of-react/
               Props => ["draft", "categories", "layout", "nav", "done", "tags", "id", "title", "created_time", "cover", "icon", "last_edited_time", "archived", "date", "slug", "ext", "excerpt"]
...

Other collections

But that’s not all. We can map other databases to collections. That’s what I did for the gists section on my website.

defaults:
  -
    scope:
      path: ""
      type: posts
    values:
      layout: post
  -
    scope:
      path: ""
      type: gists
    values:
      layout: gist

collections:
  gists:
    output: true

notion:
  databases:
    - id: 3471f31x073a43f29487f84e16618ax93
    - id: ceffc9a9152d4e4b87a786b64980e6f56
      collection: gists

Now, all gist pages will be available in Jekyll.

{% for gist in site.gists %}


I hope this short tutorial has helped you to get an idea of how to use jekyll-notion.

In upcoming articles, I will show you what else can be done with Jekyll and Notion.