How I Re-Designed My Blog

Thursday, February 27th 2020 3 mins read gatsby

For almost about 1.5 years, my domain was sitting in the dust, hosting a coming soon page. A brilliant idea occurred to me while paying the domain fees, that I should code my blog from scratch. I dusted my old HTML and CSS skills and set out to build the blog.

Just Kidding. Let's go through the process.


For the design, I just wanted something plain and minimal. I had always been a huge fan of sites like mdo, mmistakes and overreacted. Unable to decide, I mixed and matched the design ideas of all three and some inspiration from Dribbble.

I began by laying out sections of my blog:

  • Homepage: Show my projects and other stuff
  • Blog: Duh, a rarely updated blog
  • TIL: Notes to self, with search functionality
  • About: Self Explanatory
  • Tags: A hidden tags page. Not so hidden anymore.

Also, I needed that freaking Dark Mode!


I needed a lightning fast blog, and the obvious choice was a static site. But don't static site lose many features of a SSR or Dynamic site? Yeah they do, but we have to compromise on somethings, right? Keeping this in mind, I opted for the 'hybrid' site. More on this later.

Choosing a Static Site Generator which was 'feature rich' enough was a herculean task. I looked over Jekyll(too slow) and Hugo (Too complex for me and lacked many plugins). During the search, I stumbled upon GatsbyJS, which checked all the marks for my site. Based on ReactJS, uses GraphQL (something I wanted to learn for a long time), has tons of configuration support via plugins. Win-Win.

So the final stack I settled with:

  • GatsbyJS: the static site generator
  • MDX: to integrate JSX into markdown.
  • A bunch of Gatsby Plugins:
    • Gatsby Image: lazy loading, blurring placeholder and srcset support.
    • Gatsby Feed: generates the RSS Feed.
    • Gatsby Offline: uses service workers to cache website in background. Neat.
    • React Helmet: SEO stuff.
    • Gatsby Sitemap: generates sitemaps for web crawlers
  • Styled Components: cause, why not?
  • PrismJS: syntax highlighting


Writing code for the design was pretty straightforward and easy. There were a few hurdles, like:

Dark Mode

The sole functionality of this was to have a button on the header, which toggles between light and dark mode, globally. Local Storage was used to store and retrieve the theme mode. I quickly wrote down a hook that gave me a isDark boolean and a toggleTheme() function.

This is then passed to ThemeProvider of styled-components which handles changing the colors. A transition was also added to make it a bit pleasing to the eye. Find the hook here

Search in TIL

I wanted to have instant fuzzy-sort kind of search, moving the highest match result to the top. Of course, this required me to build a search index of some sort. Algolia appeared to be a viable option, but I settled with a local JSON containing titles of post (retrieved using GraphQL). This approach works for a few thousand records, as loading the search index becomes a bottleneck. It will be succeeded in some future release, once I hit 1000 posts. Check out the code here

Syntax Highlighting

For some reason, I was confused and didn't use the Gatsby Remark Plugin, which had built-in support for PrismJS. Instead, I went for setting up Prism React Renderer. Secondly, I was setting up this with MDX Shortcodes. So I spent the next 7 days trying to figure out the non-documented feature of Prism React Renderer on how to integrate the two different libraries. After pulling almost all my hair (out of frustration, of course) I had syntax highlighting enabled, it occurred to me that I also needed to implement line-highlighting and a language tag on code-block. This was the most frustrating part.

For the line-highlighting part, I was able to grab a "metastring" which contained text after the language name (looks something like this: jsx {1, 2, 10-15}, where {1, 2, 10-15} is the metastring). All I needed was to iterate over this metastring and build a list of lines which needed highlighting. Then I could simply check each line during tokenization and highlight them accordingly. Phew.

Apparently, there are some issues with fixed width container having overflowing content. This included 'the overflow hidden and right padding', 'container taking only fixed width and not total length of overflowed content', but I won't rant about them now.

Here is a example code-block:

export default Image = ({ src, caption, alt = caption }) => {
  return (
      <StyledImage src={src} alt={alt} />

You can check out the source of CodeBlock here


Alright, coming to performance. Lighthouse Audit gives 90% to performance. I'd say it's pretty quick, accounting for the fact that it loads React and the damn VirtualDom, hogging up the JS thread. In my real-world tests, the website was quick enough to load under a second on a 3G connection.

Accessibility is a different story. I am using Gatsby Image, which for some reason nests figure as descendent of p, which throws a bunch of warnings in development. I'll find a solution to it sometime later.


This all mayhem, torture and hair pulling for a couple of weeks forced me to brush up my CSS skills and taught me a lot of GraphQL. At the end, I would recommend you to code your blog from scratch, as you will learn a lot about frameworks like React, pick up few tricks on the way and get a website to show off!