April 7, 2022

For the longest time I've wanted to build a blog from scratch, something I could say I built from the ground up.

Well after years of failed attempts and moving onto the next thing I am happy to say I have finally built a blog the way I want.

What was the main difference this time? I had a clear vision of what I wanted. I have blogged before on platforms like Medium, as well as hosting an 11ty starter kit. But none of that had really stuck... I wasn't invested in the outcome, I didn't know what I wanted to write about and I had no schedule or motivators to encourage me to keep going.

So this time I outlined what I wanted to achieve long before I wrote any code. Here is a list of things I knew I wanted.

  • Something that I had built from scratch and could extend whenever and however I wanted.
  • Something that supported .mdx files which are my favourite way of authoring content.
  • Something fast with good SEO preferably a static site generator if possible.
  • Something that considers the reading experience a top priority.
  • Interactive and informative code snippets that could be easily walked through.
  • A workflow that allowed my partner to proof read my posts and provide feedback before publishing.

So with that in mind let's break down how I achieved the above.

Building something extendable

There were a couple of key critera here, I wanted something that didn't have too much magic and utilized technologies I enjoyed working with. The technologies I wanted to include were primarily React and Tailwind.

Based on my other critera in particular good SEO I had a preference for static site generators, initially I reached for Astro which I had been reading about a lot at the time and that supported React and Tailwind in the way that I wanted.

Originally I wanted to include Shiki Twoslash for it's amazing TypeScript snippets. Unfortunately I could not get this up and running with Astro. So I ended up going with Next.js which has been an absolute please to work with.

The first thing I set out to do was setup .mdx file support so I could author blog posts using my preferred format. It quickly became apparent that the suggested way of setting this up while adequate created a somewhat awkward publishing flow.

Enjoying everything else about Next.js I set out to investigate how other developers were managing their own .mdx workflow. During this time I was fortunate enough to stumble across Lee Robinson's blog which uses Contentlayer for content management. I cannot overstate how pleasant this tool is to work with, it made publishing .mdx files with Next.js an absolute breeze.

Update: Since publishing this article Lee Robinson's blog has moved over to Sanity so if you are interested in his original implementation be sure to work through his repositories history.

Setting up Contentlayer up is a relatively involved process and not really something I want to go into as part of this post, that being said the source code for this entire blog is available on GitHub so I encourage you to check it out if you are interested in trying these tools out for yourself.

Taking SEO seriously

Usually when I build something for myself I consider SEO an absolute last priority. This isn't because I don't want people to find what I'm building but more that most of what I build is for myself and I'm not really bothered about whether or not other people can find it.

Moving forward I want to change this and definitely put an effort into making myself more easily found online. Currently this means utilizing tools like next-sitemap as well as relying on a lot of the optimizations Next.js already makes under the hood.

This is definitely an area where I would like to do some further study and improve my own understanding of what makes for good SEO. In the past I have been fortunate enough to work with people well versed in this area who have handled a lot of the heavy lifting.

Making sure that reading content was enjoyable

There is nothing I love more than a blog that is primarily focused around the content it delivers, minimal use of popups, carousels, etc... I spent a lot of time agonizing over font families and color palletes (especially dark mode) this time round.

I'd read a bit about Tufte CSS and even found a blog on Hacker News that employed similar techniques. I knew I wanted something like this that really felt like it got out of the way and just let readers read!

Overall I am really happy with where I got to on this and think I achieved the aesthetic I initally set out to uncover. It is worth noting that a huge part of my success here can be attributed to the @tailwindcss/typography plugin which made styling markdown pages an absolute breeze.

Interactive and informative code snippets

This was easily the most important thing to me. In previous blogging I had noticed a pattern in the terms of content I enjoyed authoring. Most of this content was situated around the TypeScript and functional programming, so I wanted to make sure that the presentation of any code snippets had the best possible experience for the reader.

I explored a ton of options in this space and the top contenders were Shiki Twoslash, Sandpack and Code Hike.

Each of these options have serious pros and cons and I encourage you to check them all out if you are thinking of doing something similar. For myself Code Hike ended up being the best option, Shiki Twoslash actually had it beat on enhanced TypeScript support and Sandpack is arguably more customisable but Code Hike has the nicest out of the box features and allowed me to get up and running quickly. Additionally Code Hike provided the most streamlined way to provide code walk throughs which I consider to be a top priority as far as my blog is concerned.

Below is a very basic example of Code Hike in action, notice how it places extra emphasie on the function declaration?


type U<T> = T | undefined;
const trap =
<T extends (...args: any[]) => any>(handler: T) =>
async (...args: Parameters<T>): Promise<[unknown, U<ReturnType<T>>]> => {
try {
const result = await handler(...args);
return [undefined, result];
} catch (err) {
return [err, undefined];
export { trap };

Creating a workflow that made proofing easier

This was arguably the most technical challenge of setting up my new blog. Historically my partner and I had used a combination of screenshots and word documents when proofing my posts. I desperately wanted to improve this process moving forward and make it as streamlined as possible.

The challenge here was introducing a system that improved the proofing process without dictating any design decisions related to the structure of the application or adding to the overall weight once deployed.

Enter Netlify Deploy Previews 🥰 now considering I am deploying a Next.js application my first thought was to deploy with Vercel given they are the creators of Next.js after all. However Netlify Deploy Previews are just too damn good when it comes to creating a feedback/proofing loop, especially if you want a process that exists separate to your applications codebase.

I already had the Netlify GitHub App installed against my GitHub account so there really was no configuration required to get this working. The most time consuming part of the process was setting my partner up with GitHub and Netlify accounts so I could add her as a team member to enable deploy previews!


Now that my blog is officially live I have say I am extremely happy with the overall result. I set out to create something that I could call my own and I honestly feel like I've created my own little cozy corner on the internet. There is still a ton of things I would like to do moving forward and this will definitely be a place where I experiment with different ideas and technologies.

Phew! Thanks for making it this far 🥰 until next time. Stay safe out there 👋