Rebuilding my site, Part 1: Design and process

31 May 2022

Hero image

Why?

I stumbled upon a new framework recently called Astro. Being interested in front-end, it was the perfect excuse to rebuild my site in the latest new framework (🤡). However, there were several reasons why it made sense. For context, my site was built using Next.js previously.

  1. Performance. Astro builds to static HTML and CSS with no JavaScript by default. It takes an ’islands’ approach to web architecture, partially hydrating pockets of interactivity (think image carousels) where necessary compared to the all-or-nothing approach taken by Next.js. The result is a zippy site, something I wanted to optimise for as I’m conscious about performance and the fact that websites aren’t always loaded over fast connections. TL;DR: Astro is screaming fast.
  2. In-built Markdown support. Markdown is a first-class citizen in Astro. Astro turns Markdown files into a page automatically, allowing you to customise styling through the definition of a layout component. It also has smart features like allowing you to access frontmatter as props, and shipping with built-in syntax highlighting + more. TL;DR: More time spent writing.
  3. Excellent developer experience. Astro is intuitive to work with - you wrap pages in Layouts, and abstract reused elements away into Components which render to HTML. Astro comes with built-in integrations such as Tailwind, React and sitemap generation that you can toggle during setup and at any time. TL;DR: Less time spent installing packages and writing boilerplate.

The first iteration of my site was slapped together before uni started, with minimal front-end experience. With more experience under my belt after a term, from developing at UNSW CSESoc to personal projects, it was time to rebuild my site so I could maintain it easily in the coming trimesters to come.

How I did it

Defining engineering values

As I was starting from scratch, I defined several objectives which would drive the direction of my website. These objectives fall in line with my engineering philosophy.

After that was done, I went off to the Figma canva!

Designing in Figma

I prototyped my site in a single Figma file, laying iterations and breakpoints out side-by-side.

Screenshot of this site

While I’d say I’m good at design, I’m not the best, so reading Refactoring UI helped me glean some great tips to take things to the next level. Here’re some tips I’d recommend for designing your next site:

Inter’s an excellent font, but I got tired of using it too much. Fortunately, there’s an alpha variant of Inter called Inter Display, which tightens things up, is a bit taller and looks nicer at large sizes (i.e. headings). To mix things up on this site, I used Inter Display for all headings.

Going from design to code

For styling, I decided to use Tailwind CSS. Engineering is about making tradeoffs, and this was no different. The benefit of using other CSS-in-JS solutions, like Stitches, is that it doesn’t litter your code with classnames. However, for a small project like this it isn’t a problem, and I’ve found that Tailwind lets you iterate rapidly on components and translate design to code faster. Also, beautiful default utility classes such as drop shadows and spacing tokens meant I didn’t have to do much heavy lifting.

In Astro, reusable elements can be abstracted into components. Components in Astro are similar to React, but render to 100% HTML. Pages are wrapped in reusable layouts which can be nested. For example, you might create a BaseLayout.layout that’s a <div> wrapper for the page, equivalent to a <Container> or <Box> element in React. Then, you might style specific sections of your site using different layouts, nesting them inside BaseLayout. For example, here’s the BlogLayout.layout for this site:

---
// BlogLayout.layout
import BaseLayout from './BaseLayout.astro';
import { Picture } from 'astro-imagetools/components';
const { content } = Astro.props;  // Import Markdown frontmatter as props
const options = { day: 'numeric', month: 'short', year: 'numeric' };
---
{/*<!-- BaseLayout is a flex wrapper. Meta tags are passed into it.  -->*/}
<BaseLayout title={content.title} description={content.desc} image={content.hero}>
  <div class="md:mt-6 text-gray-12">
    <h1 class="mb-2 text-3xl font-bold font-display">{content.title}</h1>
    <h2 class="mb-10 text-gray-11">
      {new Date(content.date).toLocaleString('en-AU', options)}
    </h2>
    {content.hero ? <Picture src={content.hero} alt='Hero image' attributes={{img: {
      class: 'rounded-3xl w-[41rem] mb-12',
    },
  }} /> : null}
  </div>
  <article class="prose prose-headings:md dark:prose-invert">
    <slot />
  </article>
</BaseLayout>

Making my site fast, simple and beautiful

In my next post, I’ll go through how I optimised my site to be fast and included some nice touches, with tutorials for each step. Stay tuned!