Collage of mockups with my website

Behind the scenes of my website

After several months of designing, coding, and writing, I have finally published my website.

Services

UI/UX Design, Frontend Development, Content Creation, DevOps

Client

Me

Deliverables

Design system, Website, Portfolio, Blog, Newsletter

Problem

"The shoemaker's son always goes barefoot." Or maybe "the web developer is offline." Even though I started learning frontend development a while ago, I've never coded a website for myself. I've been feeling impostor syndrome and thought, I'm not good enough. But, this way, I could delay it ad infinitum. I've decided to change that. I've wanted my corner on the Internet - where I can express myself and share my findings.

Sketches

It's easier to start with pen and paper.

Keeping that in mind, I've started generating ideas. I've made rough sketches of all pages.

Different section sketches of my website

It's not Da Vinci-level sketching skills, but they were handy before making wireframes.

Wireframes

Wireframes should be a middle ground between sketches and higher-fidelity designs and prototypes. Not worrying too much about fonts and colors, I've made a lot of wireframes.

Wireframes of the landing section

Wireframes of the porfolio page

Wireframes of about page

Wireframes of the blog page

Colors

I've spent more time searching for colors than I would like to admit. But, after many hours of experimenting (and accessibility testing), I've agreed with myself. The color palette should be minimalistic and simple. It should consist of grays and whites. And, of course, with a blue accent. There is not much thought behind it - I just like blue.

Color palettes of my website

Typography

I wanted this site to be typography-oriented, so I spent another chunk of time looking for typefaces. My goal was to contrast modern sans-serif font with a more classic serif. I also needed a font for code snippets.

Montserrat - font for headings

Lora - font for body text

Fira Code - font for code snippets

Design System

Having essentials and some content, I started to create a design system. I wanted it to be flexible, consistent, and easily scalable. I made abstract design primitives (elements) like buttons and headings. I used them in many different contexts to build more complex and concrete components and sections.

Design primitives - buttons

Panda CSS is a CSS-in-JS library that allows us to define some base styles alongside multiple variants of a particular component. This way, we define a library of components that is very convenient to use. Here's how the above button component looks in code (I showed only the base styles because the original code is 300 lines long).

Defining a recipie for a button in Panda CSSTSX
1import { cva } from '@/styled-system/css'
2import { sharedTransitionProperties } from '../../utils'
3
4export const button = cva({
5 base: {
6 display: 'inline-flex',
7 alignItems: 'center',
8 gap: 's',
9 padding: 's',
10 fontFamily: 'heading',
11 fontWeight: 'medium',
12 letterSpacing: 'wide',
13 textDecoration: 'none',
14 transitionProperty: 'background-color, color',
15 ...sharedTransitionProperties,
16 cursor: 'pointer',
17 _disabled: {
18 cursor: 'not-allowed',
19 pointerEvents: 'none'
20 },
21 '& > span': {
22 flexShrink: 0
23 }
24 }
25 variants: {
26 // Button variants like primary, outline, etc.
27 },
28 defaultVariants: {
29 // Chose default variants when button is used without any
30 },
31 compoundVariants: [
32 // Compound variants allow for more complex logic
33 ]
34})

And yes - styles are written in TypeScript. It's unusual, but it's really convenient. You don't even need to remember your design tokens - autocompletion has you covered. With design primitives, components, and sections, I created responsive templates for every page.

Templates of home and portfolio pages

My design is not finished and is more like a process. I constantly develop it. Therefore, you can play "spot the difference" between this showcase and the current version of my website.

Templates of about and blog pages

I found that flexibility is desirable during the whole process. Same as breaks - it gives a new perspective. New ideas were occurring at different stages of the process and unexpected moments. Like the idea for the progress bar - I found it surfing the web. Yes, I stole it, and I'm not ashamed of that!

The only art I'll ever study is stuff that I can steal from.

David Bowie

Gatsby

To implement my website, I used Static Site Generator - Gatsby. Pages are built and optimized in the generation process, even before the user requests them. Websites created with this approach are usually more efficient than traditional solutions like WordPress.

But if pages are prebuilt, how to know which theme the user chose? Implementing the theme-switching feature was an unexpected challenge for me. But, after reading about Gatsby's build process and testing, I managed to make it work smoothly.

Next.js

"If it ain't broke, don't fix it," people say. Even though my previous website was working pretty well, working on it became harder and harder. That's why I migrated to a new tech stack. Mostly. It was also an opportunity to learn something new, so Next.js became my new framework. It's also based on React, so I didn't need to learn everything from scratch.

However, both of those tools differ significantly. Gatsby has a rich ecosystem of plugins. You're thinking about functionality, and there is probably a plugin providing it. This system is a double-edged sword, however. You can effortlessly implement a new functionality but may have a problem when a plugin is no longer supported. In Next.js, you need to implement more things manually. You need to know better what you're doing, but it's more flexible and easier to maintain in the future.

Testing

Besides manual testing, I wrote automated tests. I used Jest for component testing. To test integration between components and more complex user behavior, I used Cypress with cypress-axe. Those tests cover different website aspects - accessibility, internationalization, SEO, and more.

I also migrated my E2E test suites to Playwright. It offers full parity with Cypress and more. I won't spend much time explaining the differences between these two frameworks because I wrote a blog post comparing them - Playwright vs. Cypress - comparison of E2E testing frameworks.

GitHub

I'll try to add content and features to my website regularly, so long-term maintenance was the aim from the start. I enabled continuous integration with Github actions to minimize the number of bugs and gain more confidence in my project. Every change in the codebase triggers a series of checks and tests.

Graph of tasks in continuous integration

Playwright runs tests in parallel by default, so I could significantly simplify my CI GitHub Action. Now, it's just one job with a configuration similar to Playwright's default.

Graph of tasks in continuous integration v2

I use Conventional Commits to format messages and GitHub Flow as a branching strategy.

A newsletter that sparks curiosity💡

Subscribe to my newsletter and get a monthly dose of:

  • Front-end, web development, and design news, examples, inspiration
  • Science theories and skepticism
  • My favorite resources, ideas, tools, and other interesting links
I am not a Nigerian prince to offer you opportunities. I do not send spam. Unsubscribe anytime.