How I built this blog

In this article, I am going to break down how this blog works. When I started this project my main requirements were 1) developer experience, 2) performance and 3) simplicity.

Update July 2022: New blog theme

The stack

This blog is a Next.js application that is pulling in content from the Prezly CMS.

Using Next, you have a few options when it comes to page rendering: “on-demand” (server-side rendering) or ahead of time (static site generation). I've opted to build all the pages posts ahead of time when the site is generated (so on every deployment).

The site is deployed on Vercel (the company behind Next). The developer experience is awesome where it auto deploys the blog on every commit/merge to main.

 

Vercel Dashboard
Vercel Dashboard

For analytics I decided to use Plausible Analytics which took me 3 lines of code to set-up:

Content/CMS/Deployment

This all started as a big experiment while I was trying to figure out what we needed to do to make Prezly more developer-friendly. By trying to power an (external) blog with content written within the Prezly editor it would allow me to identify the parts of the chain that need more attention.

Every time I create or write a story in Prezly it triggers a Vercel webhook which in its turn generates+deploys the site.

 

Edit -> Webhook -> Deploy
Edit -> Webhook -> Deploy

Because of the limited number of blog posts the rebuild takes less than a minute:

 

Building blog (51 seconds)
Building blog (51 seconds)

Story Renderer

The Prezly editor stores content in a rich text format (and not HTML). This is a common practice in today's Content Management Systems as this allows for more flexibility when it comes to the rendering and management of that content. There is even a standard for it.

Here is a great article (2018) about the benefit of rich content types.

 

In Prezly's case, it means that content you write in a SlateJS powered editor is stored as a JSON object in our data store. That raw content object is fetchable through the API and we provide a renderer to then turn it into HTML.

So take this example content in Prezly:

Example content (email campaign in Prezly)
Example content (email campaign in Prezly)

The content (starting from hi %contact.firstname%) will be stored JSON:

As we're using SlateJS as an editor you can read more about the content structure (not mobile doc) in their help article. Using the Prezly provided slate renderer the code that turns this JSON object into the HTML you are reading right now looks like this:

How content is rendered can be customised by feeding options into the renderer which I had to use to display code snippets (see below).

Other Pages

For other pages such as the home page, the list of blog posts and sitemap I used the Prezly Node SDK to do some very simple API fetching.

For example, the home page that lists the latest 3 articles (source code):

Which by itself is just a simple wrapper to list content

Embedding Code Snippets

The Prezly supports embeds by making use of Iframely which natively supports github embeds (see JSON sample above). But if you have a lot of code to show off copy-pasting code into secret Github gists is cumbersome.

So I wanted to be able to show off code in a github repo or branch and Googling a solution for this got me to emgithub.com which looks to be exactly what I wanted.

Integrating the embed code in within the project was pretty clunky (dangerouslySetInnerHtml, embed.js being calls numberous times, ...) so decided to extract the code. Actually, my colleague did it for me.

So what the code is doing:

My browser fetching the code snippets on this page
My browser fetching the code snippets on this page

Styling

When it comes to styling I think I overdid it. I decided to use ChakraUI (as an experiment) but in the meanwhile I have been playing around with TailwindCSS (and more specifically with Just in Time generation). Now I want to throw out ChakraUI and switch to vanilla tailwind.

There are some upsides to using ChakraUI. For example, check out the source code for this hero component on the homepage:

Hero component on homepage
Hero component on homepage

Overall I feel using Chakra forced me to learn another syntax/way of doing things and I might be better off investing this time in properly learning TailwindCSS which can do the same stuff anyway.

Todo list

A list of things I want to do with the blog

  • Use theme-starter boilerplate code to fetch content
  • Score better on Lighthouse Audit tools
  • Allow paging from home page
  • Support Search
  • Implement subscribe functionality (stay updated)
  • Improve SEO/meta tags
  • Add RSS feed (and any other feed protocols people use)
  • Get rid of ChakraUI
  • Make better use of Uploadcare.com (using uploadcare-image)
  • Bring back sitemap.xml
  • Fetch intro text from newsroom boilerplate (make customiseable)