Brent's Lab Notebook

Notion+Gatsby CMS (The Making of This Site)

June 06, 2019

Goals

I want to publish my work more. A common theme I see among people that I respect is “working out in the open.” There are many benefits of this, but my main motivators are helping others who encounter issues by posting googleable notes and building an audience by having content. The one requirement I have is: It must be as easy as possible to author and publish new content. I should feel no polish, length, or completeness pressure: these things will only matter after the first 100 articles anyway :)

With that in mind, I’ve chosen Notion as a publishing platform. It’s one shortcut away (read: low barrier to entry for writing down new thoughts) and has a solid (private) API that should scale to the level of sophistication I need. This was hardly an original thought; this has been done before with a different tech stack.

I’ve given myself one week to complete this project. Here we go!

Saturday night: Planning requirements & research

I spent some time thinking through what I needed from this project. After an hour, I settled on the following flow:

Desired publishing flow:

  1. Create page to be published

  2. Add link to page in “Sitemap” table. This table will contain any metadata necessary to make the page.

  3. Run CI task (Can I use gitlab or netlify for this? Need to publish once a day)

This API should handle everything I need to do w/ notion: https://pypi.org/project/notion/

Requirements:

  • Hard to accidentally publish private or sensitive information

  • Frictionless to publish small posts

  • Support text, with clear path to rich media (tables, images)

Sunday night: Proof of Concept

Install notion API, take two passes at ways to recursively pull content for the blog. Settled on a table of posts w/ a “Published” toggle. This API is really fun to work with!

My script (30 lines long) pulls down a notion page, finds a table on that page, pulls all rows in that table with published:true, then converts the page linked in those rows to markdown.

Technical risk identified: Making custom UI widgets for every block type in Notion could get painful. I’m not quite sure how I would make that work with markdown, too.

Monday night: Frontend with Gatsby

Gatsby is a wonderful piece of technology. It is easy to use, familiar (built on React), and creates a nice, polished end product. They have a starter kit that I think I can use to go from zero to blog in a couple hours.

Success! I had some nasty errors messages along the way and lost an hour experimenting with different dependency combinations. Turns out, I had an extra newline at the beginning of my frontmatter file. Who knew whitespace mattered?

At the end of the night, my project is looking 10x more real:

Tuesday night: Bash time!

I have limited time tonight, so I’m going to focus on laying the groundwork for automatic site builds. At the end of the night, I have a 10 line build script that calls all the pieces I previously set up.

Wednesday night: Build automation

Finagling with Netlify getting build to run end to end. I had issues with running pipenv as netlify only supports pipenv w/ python 2.7.

Finally succeeded after an hour of tweaking build configurations. This means I can deploy my site with a push of a button or of a commit. That said, the button is inside netlify, which is no good. Now it’s time to enable publishing from within Notion.

Netlify supports build webhooks, but they work based off POST, not GET. Time to stand up a basic page that fires a POST whenever it’s loaded.

Success. It took a bit as I found out the hard way Gatsby balks at any page name that includes a dash (-). I now have a page /trigger9d4b7db1 that triggers a build whenever visited. How do I lock this down so that only I can deploy?

Now, if only there was a way to get feedback in notion when a triggered deploy succeeds…

Woke up Thursday morning with a solution: Call a Netlify API with something that will only succeed on my account if I’m logged in. Duh!

Thursday night: Post types

I added a button to view recent netlify deploys on the “build trigger” screen. Eventually I’ll want to mirror build status between netlify build and notion, but that’s out of scope for this project.

A couple polish items were added at the last minute: slugs (for prettier links) and correct propagation of the publishing date.

The last feature I’ve added is the ability to resolve the text page links. This will let me drop pages into my blog from anywhere in Notion - allowing my content to live wherever and still be published.

Done!

At this point, I’ve accomplished what I set out to do. I have a frictionless, safe way to publish my work on the web. The source code for this project can be found at: https://github.com/brentbaum/brentbaum-notion-publishing.

Next steps

  • Support for more block types

  • Clean CMS section up and publish as an open source library

  • Style blog

Notion Publishing


Written by Brent Baumgartner. He lives and works in Charlottesville at TwinThread, building data-driven products. You should follow him on Twitter