New Website 2020: Development

New Website 2020: Development

Development

I started coding with React in mid of 2018 and began to play with the thought of using React as a technology for the website. I had followed the development of the static website generator Gatsby since version 1.0 in July 2017. In September 2018 Gatsby reached version 2.0 and was finally a good option. I selected Gatsby because of its massive community, fantastic plugin system, its utilization of React, GraphQL, and a static page generator.

This essay has no code examples, as it’s more a description of technological decisions I took and problems I ran into, and how I solved them. The whole source code is publicly available on GitHub.

Setup

Between the end of November and mid of December 2019, I worked on the basic setup of the project, which took 28 hours. I created a fresh, empty Gatsby project. I don’t remember which starter I used, but it was one of the most basic ones. The concept of Gatsby Recipes wasn’t released yet, I had to do all configuration manually.

Every project I work on these days needs Prettier installed. I don’t even want to remember the times before, Prettier. Formatting and indenting are not issues anymore you think about, you write your code, and it gets automatically reformatted and re-arranged.

Next, I installed Husky, a tool to add Git hooks to a project that allows running specific commands before or after specific Git commands. With Lint-Staged which allows running linters on Git staged files, it’s the best toolkit to prevent oneself from committing invalid or broken code.

I installed Commitizen a tool that helps format Git commit messages with the AngularJS commit message convention. This creates good commits that can be identified later and encourages atomic commits—meaning not condensing a documentation change and a bug fix into one commit, but separating them into two different commits. This allows later to identify what was changed and why. Nobody likes looking at a 2,000-line commit including changes all over a code-base.

I used EditorConfig, a nice convention for ensuring consistent coding styles on a project. It wouldn’t be necessary on my website because I’m the only developer working on my website, but I like to have an industry-standard start even on private projects.

TypeScript

Next, I configured TypeScript in Gatsby. The setup is quick and easy, using the gatsby-plugin-typescript plugin. I decided early I wanted to use TypeScript on my whole project, even though this would slow me down. I started learning TypeScript a few months earlier, but I wanted to invest in learning the technology because the whole industry moves to TypeScript, including my current employer.

The initial start was rough because I had no idea how to properly structure a Gatsby/TypeScript project. But by looking into other TypeScript starters, I found good inspiration on how to do it properly.

The first two weeks were tough, and I cursed a lot at TypeScript, but then the development got quicker, and I could reuse a lot of what I learned.

Linting

I installed tools for static testing, linters for JavaScript/TypeScript (ESLint) and CSS (Stylelint). All linters check automatically every line of code I wrote before I commit them.

Unit Testing

A good code-base should have proper unit test coverage, which is why I installed and configured Jest as a testing framework and used React Testing Library for its fantastic set of testing utilities. Additionally, I added Jest Axe a Jest matcher to identify common accessibility problems.

Each of my components has a snapshot test that covers the Markup and CSS, and an Axe accessibility test to catch preventable problems. Plenty of people think Snapshot tests are a bad habit, but I disagree and during my development, I was proved correct. The snapshot makes sure you don’t accidentally break Markup or CSS without at least acknowledging it. Interactive components have additional integration tests checking for the correct handling of interactions.

Styled Components

I decided to use Styled Components as a CSS in the JS library. I long opposed to the idea of CSS in JS, and I dislike libraries that don’t use CSS syntax. I hate writing CSS in objects or JavaScript syntax (borderBottom: "10px" instead of border-bottom: 10px). But using Styled Components makes the development of components a lot faster. And it’s convenient to generate TypeScript types automatically out of variants with keyof typeof variant.

I picked Styled-System as an additional library but ripped it out later in the process because it was over-engineering for my one-person website. I don’t need super-flexible components that can be changed on the fly by a developer. I’m the developer on the project, I know what I need.

Theming

I used the Theme Provider of Styled Components to prepare my website for a light and dark theme (plus theme color variations). Coding the theme toggle was the hardest part of the whole development. It took me a good two weeks to get a working theme switcher with a theme context running. Yet, I didn’t know that worse things would come, but more to that topic later.

MDX

One of the reasons I was happy to use Gatsby on my new website was the support of MDX (Markdown with JSX). Since the early days of blogging, I was always annoyed by how hard it was to get custom things into a blog post. WordPress introduced the concept of shortcodes which was a big thing. But this is nothing compared to what MDX can do: MDX allows it to develop complex components doing what you like and then add them as normal HTML tags in the Markdown documents. This allows for interactive posts or custom-styled tags.

And the best thing is: Thanks to the MDX Provider, it’s possible to automatically provide every Markdown document with your custom components without the need of manually importing them every time. You can remap standard Markdown tags to your components.

Blog

Next, I tried to get a basic blog running by adding sample MDX files and using GraphQL to query the data and display it on the homepage. Nothing fancy, to kick off things. I didn’t work any further on the blog for the next few months.

Code Highlighting

As I write sometimes essays with code examples, I needed code highlighting. A common way of doing this is using a JavaScript library like PrismJS. I added the library and the Gatsby plugin but wasn’t happy with the solution. The library is big and slows down the loading. And all that to get code highlighted.

But then I found the community plugin gatsby-remark-vscode, and it’s magical. It allows you to use any Visual Studio Code plugin to be used on your website: Themes or syntax highlighting are the most commonly used. You don’t need to rely on the library of JavaScript library to support your wished syntax. If Visual Studio Code supports it, it will be running on your website. I picked my favorite color theme and added it to my project. Additionally, the plugin has a huge number of options, for example, changing themes matching the color scheme preferences or contrast preferences or highlighting specific lines or ranges. And the best thing is: Everything is pre-rendered, you don’t need to load one line of JavaScript for the code highlighting.

Persistent Theme Toggle and SSR Rendering

The last thing I coded on Sylvester’s day 2019 was a persistent toggle, preselecting your color options by reading your system’s preferences and saving your preferences to a persistent state consistent across multiple tabs.

But in mid-January, I recognized a strange behavior: My color theme didn’t work as expected after I built the Gatsby site for production. There was always a flash and styles didn’t change consistently across the whole website. I was nerve-wrecked after coding for 3 weeks on the color scheme, everything now for nothing.

After debugging for a few days, I could narrow down the problem to the SSR (Server-Side-Rendering) of Gatsby. Gatsby creates a static website of all your pages that will run without any JavaScript. JavaScript adds a better experience and a better response to a website. And to render everything to a static file, the default theme gets picked (which was the light theme in my case). Even after React is loaded, it won’t replace the light theme with the dark theme automatically. You would need to trigger a manual re-render of the whole page, which looked like an unfavorable solution to me. Luckily, other people ran into the problem and I found out that the easiest solution is to move the colors from the theme provider into CSS Custom Properties (aka CSS Variables).

In the end, I solved the problem by using a few global JavaScript functions to change the theme by applying a CSS class to the body tag and then switching the colors thanks to CSS variables. This works perfectly and has a good performance. Plus: I didn’t need the Theme Provider anymore and could remove it.

SEO

In January 2020, I created an SEO component. As long as I work with websites, I know the importance of an SEO-friendly website. If the website can’t be crawled properly it will be bad for disabled people, content crawlers (like Raindrop.io or Pocket), or Feed Reeders) and sharing content on social media won’t work properly. Bad SEO: Your website sucks.

The component I created (I was inspired by a lot of other Gatsby developers) provides every page with the full set of necessary headers: Meta tags, title, description, OpenGraph, and 𝕏 tags (for sharing on social media sites) and plenty of other things. The component allows changing any of these parameters on a per-page basis. A specific page shouldn’t be crawled? Add a different robots rule to that page.

Easter Eggs

I started with coding the most unnecessary components first: The Easter eggs. 😬 But as I wanted the website to have uncommon and never-seen-before features, this was important to me. Next to my favorite Easter egg, I coded a LocalizedDate component, which allows the visitor to pick between three different date formats: US, German, or Japanese. Your selection will be remembered in your browser. I admit I did it because I like how the Japanese date looks but didn’t want to torture my visitors with the format.

I coded January the ColorSwatch component, a component that can display color and its values. I knew I would need this later.

SVG Generation

I created a script to generate components from SVG illustrations using SVGR. It took me a little bit to find out how to make the script export TypeScript components, but could, fortunately, figure it out.

I use the beautiful and minimalistic Remix Icons and custom icons created by me, but try to use as few icons as possible.

Web Font

The last thing I did in January 2020 was added the web font to my website. I knew from the beginning I didn’t want any dependency on a font provider, and definitely not Google. I removed all page tracking in 2019 from my website and don’t indent to add any tracking back. Adding a web font from Google Fonts will automatically bring user tracking. Additionally, the performance is never as good as if the font is directly served from your server.

That’s why I found a high-quality version of Playfair Display (Google does something to the fonts) and converted them with Font Squirrels free generator into all the necessary formats.

I use the Web Font Loader to asynchronously load the fonts. The library adds specific classes to the html tag, reflecting the different states of the web font loading. This allows swapping fonts or changing CSS depending on the state of the loading. I load initially the font Georgia in a different font weight that allows the minimal amount of jumping text when the web font is finished loading.

Components, Components, and More Components

From February 2020 to April 2020 I did one repeating thing: Developing components. I added components for typography, links, code blocks, text styles, quotations, lists, footnotes, and many more. It was a tiring process, but I knew I would need all these components.

After a few components, I got tired of always copying and pasting the folder structure of a component that I installed Plop. Plop can be used to auto-generate any file and folder structure, including automatically naming everything.

Component-Driven Development

I never worked with Storybook before, but I always wanted to try it. Storybook is an open-source tool for developing UI components isolated. It has a giant community creating plugins for every thinkable use case.

I moved all my existing components to Storybook and started with a component-driven development. I created one story (a use case) for every component variation. Then I developed the components isolated from any website code in Storybook and unit tested the stories. This made the development much easier and fun than creating a manual style guide page and developing the components on that.

Grid

In mid of May 2020, I started developing the page grid, row, and column helpers. The underlying technology is CSS Grid Layout. I wanted the grid to be as flexible as possible: Supporting explicitly placed grid items, but different size presets for simple pages and allowing content to be auto-placed on the grid if possible.

I ran into a problem because of all the designs I created for the huge Desktop size of 1800 Pixels. Each grid module was 100 × 100 Pixels wide. But a responsive page isn’t concerned about pixel sizes.

Responsive Grid and Typography

Lucky, I stumbled upon a video about min(), max(), and clamp() a few weeks earlier. I had never heard of clamp before and was surprised by how supported it was. IE11 doesn’t support it, but who cares about that crappy discontinued browser? Not even Microsoft.

The combination of min(), max(), and clamp() allows responsive typography or grids, that respect a minimal and maximal size and adjust the size of anything in between these two values matching to the available screen space. This changed everything! I switched all font sizes and space tokens to clamp. This allows the grid, margins, padding, or font sizes to adjust to the screen size but stay within reasonable ranges.

Pages

At the end of May 2020, I started creating the first page: The Error 404 page. I used explicitly positioned content and could test out my grid.

Next, I created the first Markdown page: Imprint. And then the About page, another explicitly designed page. It was impressive how quick and easy it was to create all the layouts I designed months earlier in Affinity Designer. Each page took me a day. I created the first parts of the Homepage, another explicitly set site.

Then I started with my first data-driven pages: The Traditional Colors of Japan and Haiku.

I created the colors a few years ago from a Japanese book about colors. Back then it was a blog post, but I always intended to create a full page around that, presenting all the colors in a space they deserved. I read all the color values from a YAML file and generate the page thanks to GraphQL with Gatsby using my Color Swatch component I developed a few months earlier.

My Haiku (Japanese poetry) were always cramped on one boring page on my previous website, and I wanted to present them properly. I created a proper introduction page with an explanation and information and listed all my Haiku. I generated for each Haiku an individual page, including an English translation of my in German written Haiku.

In Mid of June, I started creating the Journal aka Blog. I created a two-column layout with all essays sorted alphabetically on the left side and all monthly recommendations sorted by date on the right side. As the date is for my essays of minor importance (except the recommendations), alphabetical sorting is the best option. I created the Journal detail page, displaying an individual essay.

I created a sophisticated Row component a month earlier that can automatically align content by a fixed set of rules, and needed to make it work on small screen sizes.

I thought long about dropping the Projects page from my list for the initial launch of the new design because I had worked on the project for a long time. But then I decided to do it and invest in the two additional weeks because now is always the right time to do things. I not only created a Projects page but showcases for selected projects.

While showing all my projects, I decided to move my Sketchnotes to a dedicated section on the website.

Migrating the Content

I knew one last big task was left on my list, which was tedious work but needed to be completed: Moving all essays to my new website. This took me a whole week because I decided to correct the spelling of every essay, needed to replace custom HTML with my components, and update the YAML Frontmatter metadata of each blog post. I decided to improve the quality of the images when possible.

Recent Essays on the Homepage

The homepage was missing a design for the recent essays. My early designs in that section didn’t please me anymore, they were aligned, boring, and blunt. I decided to experiment with a Grid automatically reordering itself and content randomly offset. The idea worked, but the randomness will reposition the recent blog essays each time I deploy my website, as the SSR will embed the styles and prevent a new random positioning on each reload.

Animations & Transitions

The last bigger tasks on my list were related to Animations and Transitions. I had moved these to the end of the development, to be able to ship without them, if it got complicated or time-intensive.

I used React Transition Group and gatsby-plugin-layout to be able to transition between different pages. I kept the transition simple and pleasant to stick to the principles of Shibui.

I used gatsby-plugin-scroll-reveal to reveal content when scrolling into the viewport. The plugin uses Sal.js as a scroll animation library.

In the end, I improved the performance of all transitions on my website by changing what I transitioned. Early on I had quickly added simple transitions but got a low-performance warning from Jest.

Progressive Web App & RSS/Atom Feed

The last thing I added to my website before I got ready to launch it was converting my website into a PWA (Progressive Web App) by adding a Service Worker. With Gatsby, this can be achieved with the plugins gatsby-plugin-manifest and gatsby-plugin-offline.

The last task on my list was adding an RSS/Atom Feed. I thought this would be an easy task, but I was wrong. I tried using the plugin gatsby-plugin-feed, but couldn’t get it running. I tried another community plugin forked to support MDX, but ran into the same problems. The content didn’t want to render properly, all my custom MDX components were missing. Debugging was hard because the feed gets only generated with a production build, which is why it took me multiple hours to debug the issue. In the end, I found out accidentally, that I had to move the MDX Provider from my layout component to the wrapRootElement function. Lastly, I changed a few of my components to be better displayed in the RSS feed.

Continuous integration & Deployment

I use Netlify to host my website. When I open a pull request on GitHub, Netlify creates automatically a preview deployment on a custom URL. This is a fantastic feature and the main reason I selected Netlify. An automation workflow checks the Redirect file, mixed content, and other changes.

I use Travis CI to run the CSS and JavaScript linting and the automated tests with Jest (including coverage). The coverage report gets automatically uploaded to Codecov.

I added the Renovate bot to automatically open pull requests for package upgrades but removed it later because it would quickly use up my free build minutes on Netlify.

Source Code

If you’re interested in how I developed each step of the website, I created nearly 500 Git commits. You can check out the source code of the website at any selected time and look into how the website looked.