How I built my website
—4 min read—Corbin Child
Welcome to my website!
It took quite a bit of research to assemble a "tech stack" that met my requirements. There was no perfect out-of-the-box solution for a lightening fast, flexible, and static website — that is also SEO friendly. The solutions that do exist unfortunately place limits on the interactivity and flexibility of the final website. I thought I could do better than that, so here are my thoughts.
My requirements
React and TypeScript
I have built many web-based projects using React and TypeScript. I am familiar with them both and they are fantastic. Community support is first-in-class and the development experience is painless.
I don't want limitations on what my personal website is or will become. Sure, at present my website consists of a few static pages and some markdown articles. But down the road I may want to build a page that contains an interactive demonstration of my work or similar. I need a tech stack that is powerful and flexible.
Writing articles
If it's annoying or finicky to write an article, I simply won't do it. Even writing articles in plain HTML — with a number of <p>
tags in a <div>
is annoying enough. The answer for me (and many others) is markdown of course.
Static site generators (known as SSGs) like Gatspy and Gridsome provide an undeniably wonderful authoring experience. All you have to do is touch
a new markdown file in the appropriate directory. Then get writing. However, during my research I found that markdown-based SSGs were all very opinionated and restrictive. Mixing React and Markdown on the same page was either impossible or tricky. If it's possible, it likely requires some plugin/module/extension, config file, blob of boilerplate, or hack.
Static page generation
As much as I love the Jamstack, it has some significant downsides from an SEO perspective. Many blogs powered by a "headless CMS" require two round trips before rendering the blog content (one to fetch the static JavaScript bundle and another to fetch the blog content from a Content Management System (known as a CMS). This degrades page load speeds and user experience, which can impact search engine rankings.
I want every page of my website to be pre-rendered so that it delivers entirely static assets to the user's browser. It can then be deployed them to a Content Delivery Network (known as a CDN) and deliver fast page load times worldwide.
The solution
Next.js
After much deliberation I decided to build my site with Next.js. This won't be a surprising decision to anyone who's played with statically-rendered or server-side rendered React in recent years. Next.js has become the most popular platform in recent years, for commercial applications and hobbyist projects alike.
Next.js is by far the most elegant way (for now) to do any static generation or server-side rendering with React. Version 9.3 of Next.js, released in March 2020, included a static site generator with sensible and easy-to-use hooks for state management and routing.
Both React and TypeScript are baked into Next.js out of the box, so you get these for free when you set up a Next.js project.
Markdown
Using Next's special getStaticProps
hook and dynamic imports, it's a breeze to import a markdown file and pass its contents into my React components as a prop. This achieves my requirements: the ability to easily mix React and markdown without overworking the solution.
Frontmatter support
Every markdown file includes a "frontmatter block" containing metadata. I implemented a simple utility function that loads a markdown file, parses its contents, and returns a TypeScript object with the following signature:
type PostType = {
slug: string;
date: string;
title: string;
description: string;
time: string;
};
I implemented a separate function that loads all of the markdown files under a /data
directory and returns them as an array. I then render a list of articles with some of the properties listed in PostType
above.
Design
I used the helpful next-mdx-remote
package to render markdown as a React component with minimal Medium-inspired styles. Tailwind CSS is my CSS framework of choice, because it is flexible and and lends itself to fast prototyping and design iteration.
SEO
Every page on the website (including article pages) automatically populates meta tags based on the post metadata. This includes a title
tag, meta
tags, og:
tags, Twitter metadata, and a link
tag containing the canonical URL for the website.
Hosting
The website is hosted for free by the wonderful folks at Netlify. Each time an article page is created or amended, Netlify processes a new build of the website and pushes it out to the world. The process is automated and is simply triggered by new commits to GitHub.
Closing thoughts
Overall, the tech stack I have selected is well-integrated, supported by a large community of developers, and very likely to remain relevant in the fast-changing world of JavaScript web development for years to come - or at least until I get bored and decide to change everything!