It passes WCAG AA, is SEO and social friendly, I used React, NextJS, TypeScript, Sass, plus Notion as a CMS. Here’s how I put all that together.

Articles/

Why I rebuilt my personal website

Firstly, my old site was getting stale. I built it as a custom WordPress theme back in 2014 and, while some parts of the visual design still felt relevant, the tech was way out of date.

I wanted to learn React (to a point) in order to better collaborate with our developers at work. React is an important layer in our tech stack and it’s good to have a little knowledge about these things when designing products.

Lastly, I’ve learnt so much about accessibility over the past year and I wanted to put that into practice. To see if I could use what I now know to make my own site WCAG AA compliant.

Updating the visual design

rwuk-old-site.jpg

The branding on my old site was all essentially a play on my name: Winter. Everything looks cool and crisp. Not a rounded corner in sight. My image in the top corner tilted on a 45 degree ski slope, and a snowflake added to the end of my name in the form of an asterisk.

Rather than spend time mucking about with different fonts & a whole new vibe, I brought most of that along to the new site so I could spend my time on other factors:

  • New responsive layout that uses more modern CSS and rests upon a set of React components.
  • Ensuring it loads fast, with images that use my @1.5x compression technique (article on designing for performance coming soon).
  • An accessible colour palette, let’s explore that part next.

Making it accessible

Colour

The challenge was that I wanted a teal colour for my brand. Teal is a mix of green & blue, and green is a notoriously difficult colour to make accessible in this way as it results in low contrast.

What I was looking for was a tool with background & foreground options, a picker with HSL (Hue Saturation & Brightness) plus value fields that I could nudge up & down with my keyboard to tweak the colours & find a colour for my links that is saturated enough to look inviting, yet holds enough contrast to pass 1:4.5, which is a WCAG AA rating for small text.

Found the ideal colour contrast picker on Coolors. I recommend checking this out. It had exactly the level of usability that I wanted to find my ideal teal.

coolors-colour-contrast-checker.jpg

Screen reader support

I made sure all images have alt text. This was done in a few different ways:

  • Notion doesn’t offer an alt text field for the main cover image on each card link, and each page. So I set up a new property to add this as custom text. It’s really easy to see if there’s a piece of cover image alt text missing in the Notion database so that works really well.
  • Inline images in the body of an article have a caption field that, when parsed through the Notion to Markdown JS library, turn the captions into alt text. This is great as I was planning on doing exactly this as a manual override somehow, but it seemed to work out of the box.
  • Icons in the nav bar also need some kind of alt text, although that’s simply hardcoded into the React component that I use on each page for the navigation.

I needed to add ARIA labels to the social media icons in the nav bar as they have no visible text.

<Link
	className="nav-social-link"
	href="https://www.twitter.com/AllStarBob"
	aria-label="Link to Rob Winter's X profile - formally known as Twitter"
	target="_blank"
	rel="nofollow"
>

Accessibility testing

accessibility-testing.jpg

To check all these things I used a combination of two Chrome plugins:

  • Wave
  • ARC toolkit

Both have their strengths & weaknesses but as a pair they seem to pick up all the technical issues that can arise when putting together a new site.

Of course, the tougher test is to walk through the site using keyboard controls only, using a screen reader, using some kind of colourblind filter, and then see what accessibility issues remain.

Styling with Sass is near perfect

Sass is great for splitting up long CSS files into lots of small ones.

This is great when you’re building a React app as it’s essentially all about making lots of reusable components. And each of those components has a separate TypeScript file.

So, it’s logical, and easier on the cognitive load for developers, if the styling files follow the same one-file-per-component approach.

I use a file structure that I learnt many years ago from a guy called Harry Roberts. He runs a site called CSS Wizardry, but these days he focusses on performance more than styling.

Harry calls this the ITCSS framework - Inverted Triangle CSS.

To compile all these Sass files together, I used to use an app called CodeKit, made by an indie developer called Brian Jones. This is an excellent app for those starting out with Sass as it takes away all the complexity of setting it up.

But… NextJS can compile Sass files into a single CSS file very easily. So no need for a separate application to do this work.

Only drawback with Sass is with system colour modes. For that I found it was best to use native CSS variables. That way I could create a set of colours that would kick in when the user’s preference is dark mode, and it all works like a dream.

Maybe blending both Sass variables and native CSS variables isn’t a purist’s approach to writing code, but it’s achieved what I need and does it elegantly so I consider that a win.

Here are the basics of setting up the colour mode variables. The user’s preference is detected by the browser and the corresponding vars are used to colour everything in the site.

:root {
	/* Core vars */
	--teal: #007D96;
	--teal-tint: #00879e;
	--teal-pastel: #e7fbff;
	--darkest-grey: #222222;
	--dark-grey: #545454;
	--mid-grey: #b4b4b4;
	--light-grey: #eeeeee;
	--lightest-grey: #f8f8f8;
	--white: #ffffff;

	--body-bg: var(--lightest-grey);
}

@media (prefers-color-scheme: dark) {

	:root {
		// Dark mode core
		--teal: #0098B3;
		--teal-tint: #00b0cf;
		--white: #ffffff;
		--dusty-teal: #708FA0;
		--mid-grey: #b4b4b4;
		--light-grey: #eeeeee;
		--dusky-blue: #002F49;
		--midnight-blue: #001B2A;
	
		--body-bg: var(--dusky-blue);
	}

}

body {
	background: var(--body-bg);
	// This one property looks for the --body-bg variable in either set of colours
}

Learning React & Next.js

Initially this part of the build was surprisingly easy. But it quickly got more complex.

Setting up a NextJS site running locally on my mac was a breeze following some tutorials on YouTube.

I really like the tutorials made by a guy called Mosh Hamedani. He’s got a cool accent, a relaxing tone, and a superb way of explaining things that’s easy to follow and keeps stepping up your skills without you realising it.

There seems to be endless ways of achieving the same result with React, each with their own learning curve. This makes me feel like I’ll always be a complete newb in the JS community, but that’s ok, I’m better at other things 😏

Typescript is complicated

The tutorials I was following used Typescript. And so in order to match their code precisely, and also to learn some new tech – alongside all the other new tech I was learning in this project – I set up my Next.JS app to use the TypeScript compiler too.

OMG it’s hard. Much more strict that writing normal JavaScript. As a newb I found this to be the biggest annoyance as even slightly poorly written code seems to result in the entire app not working. It forces you to follow the data around your code and flush out every issue.

Without the help of AI assistants I never would have navigated this part of the build successfully.

Google Bard served me well at first but, as I became more familiar with the code I was manipulating, I realised it was starting to return suggestions that were just plain rubbish. Fabricated out of thin air, as we know AI can do.

I found ChatGPT to be a far superior AI assistant when it comes to questions about code.

Using AI to help in these sticky situations feels like having a code mentor sitting next to you. This is a truly incredible way to learn and solve real technical problems at the same time.

Say what you like about the downsides of AI, but I think we live in exciting times for tech.

Using Notion as a CMS

notion-as-a-cms.jpg

I love Notion. I’m known at work for being that guy who won’t use Google docs or sheets anymore. All my documentation and project management happens in Notion.

When I’m writing something in Notion I tend to enjoy the experience more. I gravitate towards writing in Notion more deeply.

So I wanted to see if I could use Notion as my CMS. After all, they have an API, so how could I hook that up to my NextJS front end?

As usual, I started by finding a few tutorials on YouTube. One of them stood out as particularly relevant and didn’t seem too long.

Every time I got a new piece of my site working via the Notion API I felt a surge of achievement.

I was one step closer to having my ideal app as a writing tool, that could publish directly to my own website.

As I sit here typing right now, I’m literally one click away from pushing this content to the world. And that ‘s something I’m proud of building.

Rob Winter, researcher, designer, coder, manager.

About the author

Hi, I'm Rob

I make digital products that help improve people's lives.

After working my way up to the top of the design function in my earlier years, I began a broader role with a new startup - Life Moments - in 2018.

I've been a pivotal force in shaping and operating the business from its inception to profitability and beyond.

Find out more about my career.