How I made this site with Gatsby, ConvertKit, and Netlify

Over the years, I’ve started a few blogs but I never got serious about it. They were soon abandonware. A few days ago I found Swyx’s How to Market Yourself and it made me think. My online presence was not much.

Around the same time, in an email Joel from egghead said:

Your voice is important. Everything that needs to be said hasn’t been written down yet. You don’t need to write masterpieces, just to share solutions to problems that you have. We will all appreciate it.

That is when I decided to make a personal website and share with you the things I think are worth sharing.


From the start I decided to implement the site in React and build it with Gatsby. This was an easy choice because I like to code with both of them and have a ton of experience with them. And of course, I wanted my site to be blazing fast 🔥.


After a quick lookup, the obvious starting point was supposed to be the Gatsby starter blog theme.

gatsby new homepage

But I soon ran into a showstopper: there was no way to change the default heading font.

Gatsby has these concepts of plugins, themes, and starters:

I wanted to use the blog theme because I wanted to add additional themes, to make a website that has a blog section but also something else, maybe a portfolio/projects section, maybe an e-commerce section (since I’m planning to make some courses). So the theme was the perfect choice.

The themes are supposed to be customizable in a certain way: you could overwrite any source file from the theme by creating a file with the same name in your project. This is called shadowing. Now there are two problems with this (at least today):

For example to create my own bio.js component I created components/bio.js. To overwrite the Theme UI files, I created a folder called gatsby-plugin-theme-ui and created all the files from it to showdow those from the theme since I wanted my very own styles.

├── gatsby-config.js
├── gatsby-node.js
└── src
    ├── components
    │   ├── bio-content.js
    │   ├── bio.js
    ├── gatsby-plugin-theme-ui
    │   ├── colors.js
    │   ├── index.js
    │   ├── prism.js
    │   ├── styles.js
    │   └── typography.js
    └── templates
        └── post.js

The problem was that I couldn’t shadow gatsby-plugin-theme-ui/index.js which defined the fonts for the header and monospace fonts:

import merge from "deepmerge";
import typography from "./typography";
import colors from "./colors";
import styles from "./styles";
import prism from "./prism";

export default merge(typography, {
  initialColorMode: `light`,
  fonts: {
    heading: `Montserrat, sans-serif`,
    monospace: `Consolas, Menlo, Monaco, source-code-pro, Courier New, monospace`,
  sizes: {
    container: 672,

Initially, I wanted to open an issue on this, but the gatsby-theme-blog is not a separate project on Github, but part of the Gatbsy project so I moved on (for the moment, I still want to hunt this down at some point, otherwise Monserrat will be the default font on a ton of Gatsby blogs).

There were some other little annoying things with this theme, like not including the external links plugin, and thus all the external links were opening in the same tab.


In the end, I had to use the Gatsby starter blog

gatsby new gatsby-starter-blog

I copied over here what I liked from the gatsby-theme-blog and moved on. Now I was able to customize it as I wanted.

One of the things I’ve made differently is styling. I know there are a ton of styling options these days but I prefer plain old CSS files. I have three of them:

That’s it. React components set only class names and not inline styles. I like to keep things simple. I might move to SCSS if things get more complex, but for now plain CSS plus CSS variables are OK.

Saved theme problem

You can change the theme and that is saved in the local storage using a React hook. The problem was that the saved theme is read by React after the hydration (site is rendered server-side with Gatsby with the default light theme). And this caused the initial rendering of the site using the light theme even if your preference was the dark one.

To fix this, I had to override the Gatsby default html.js and read the saved theme sooner. Here is the interesting bit:

    __html: `
        var theme;
        try {
            theme = localStorage.getItem('theme');
        } catch (err) { }

        if(!theme && 
            window.matchMedia('(prefers-color-scheme: dark)') && 
            window.matchMedia('(prefers-color-scheme: dark)').matches) 
            theme = 'dark'
        document.body.className = theme || 'light';

As you can see something else is going on: if there is not saved theme, the theme to use matched the system one. So if you are using on your computer a dark theme, the site will be displayed by default with the dark theme. (I know, is not working in IE11, who cares?)


I already had a few other sites on Netlify so I decided to host there also this one. I simply love Netlify. It has a great free plan that is enough for me (for now at least.)

Using, Gatsby and Netlify together, the site a blazing fast indeed. It managed to get a near-perfect high score on Page Speed Index.

One strong alternative would have been Vercel (ex Zeit). As far as I see they provide the same features as Netlify.


The newsletter was the final step. There are a lot of options there but I was too lazy to verify all of them and choose the best. I’ve heard about ConvertKit good things and I know Nathan Barry from his book, Authority. So all other things being equal I’ve gone with ConvertKit.

As soon as I started using ConvertKit with my Gmail, it complained that I should use my personal domain email. Netlify doesn’t provide email service but it allows you to set up the Netlify DNS records to use another service.


Dan Abramov’s site, was my starting point. It is open source and is also build using Gatsby Blog Starter. It was incredibly helpful to see how Dan solved some of the issues I also had, especially the flash of unstyled content and the ConvertKit form integration. Thank you, Dan! I’m thinking about making this open source also.

iA Writer is my favorite writing app on iPad and there I found the IBM Plex sans font.

The dark theme was a bit hard to get right and I’ve used Teresa Man’s ideas.

The story of the lightbulb 💡☝️

There are two themes: a light one and a dark one. The default one is the same as your system: if you are using a dark theme on your system, this site’s theme is also dark. But I wanted to allow you to change it.

I didn’t want to use the default toggle button(with the sun and moon as on and I also wanted to add a unique touch. And thus after a few iterations on different ideas, I chose the lightbulb.

Besides the functionality it provides, to change the theme, the lightbulb attracts the eye since it is the only fancy decoration on the page. Also since it’s an SVG, I’m using it to create various site icons.

The end

I’m just starting, there are still things to be done, but so far things look good. My goal was to start this site with free but excellent services and I think I was successful. It’s incredible what you can do these days even without a credit card. Thank you all.

You should start a site too. As Joel says:

Your voice is important. Everything that needs to be said hasn’t been written down yet. You don’t need to write masterpieces, just to share solutions to problems that you have. We will all appreciate it.

Want to learn more?