space city
frontend developer

Creating my website

I've been working on this site intermittently for months, utilising various approaches and tools as opportunities to explore interesting technologies. After many attempts and approaches I eventually landed on the Remix framework. Code can be found here.

Remix

I remember watching this video for Remix beta v1 some years ago and and I found it genuinely exciting. In particular, the handling of forms with a server action. When I needed to implement a login form for my site, I saw it as a perfect opportunity to try Remix, and I was delighted with the developer experience. Although the login form is currently not in use, you can still view it here.

My initial goal was to build a blog site where I could directly add and edit content like a cms. However, for the time being, I've decided to utilise MDX, given Remix's excellent support for it. Additionally, integrating Vite into the mix has made this approach even more appealing.

I will be posting more detail on what I have learned along the way in future.

Styling

In my day-to-day work over the past few years I have been using styled-components, Emotion and component libraries such as Material UI and Chakra UI.

It has therefore been a while since I've used regular CSS extensively and I had not previously used CSS variables before so decided to do that here. I don't consider myself a designer, and so for this theme I looked into some ideas around cyberpunk and sci-fi genres and aimed to create a theme reflective of those.

Below are my css variables for my theme.

:root {
 --clr-primary: hsl(322, 46%, 70%);
 --clr-secondary: hsl(199, 49%, 55%);
 --clr-alternate: hsl(323, 22%, 47%);
 --clr-grey: hsl(208, 88%, 83%);
 --clr-bright: hsl(180, 100%, 97%);
 --clr-dark: hsl(237, 43%, 10%);
 --clr-dark-red: hsl(288, 43%, 9%);

 --ff-primary: 'Roboto Mono', 'Helvetica', 'Arial', 'sans-serif';
 --ff-body: var(--ff-primary);
 --ff-heading: var(--ff-primary);

 --fw-regular: 400;
 --fw-bold: 700;

 --fs-300: 0.775rem;
 --fs-400: 1rem;
 --fs-450: 1.125rem;
 --fs-500: 1.375rem;
 --fs-600: 1.875rem;
 --fs-700: 2.5rem;
 --fs-800: 3rem;
 --fs-900: 3.5rem;

 --fs-body: var(--fs-400);
 --fs-primary-heading: var(--fs-600);
 --fs-secondary-heading: var(--fs-500);
 --fs-third-heading: var(--fs-450);
 --fs-nav: var(--fs-500);
 --fs-button: var(--fs-400);

 --spacing-100: 0.375rem;
 --spacing-200: 0.5rem;
 --spacing-300: 1rem;
 --spacing-400: 1.5rem;
 --spacing-500: 2rem;
 --spacing-600: 3rem;
 --spacing-700: 4rem;
 --spacing-800: 5rem;

 --transition-duration: 0.3s;

 --border-radius: var(--spacing-200);
}

@media (min-width: 48rem) {
 :root {
   --fs-body: var(--fs-450);
   --fs-primary-heading: var(--fs-700);
   --fs-secondary-heading: var(--fs-600);
   --fs-third-heading: var(--fs-500);
   --fs-button: var(--fs-450);

   --fs-nav: var(--fs-300);
 }
}

Deployment and hosting

There are some great options for deploying and hosting a website for a low cost or even free. I tried Vercel and Netlify free tiers which are both excellent but they both host in the US by default which comes with performance issues for me being in the UK. Options to improve this, such as CDN and region host changes, add additional cost.

Remix comes with a great option to enable deployment to AWS using Architect of which I did use for a while and could host in the UK and retain no costs.

I then discovered SST which has slightly more complexity to the config than Architect, but automatically sets up CloudFront for you, as well as your local development environment connected to a live AWS Lambda.

I won't go through every detail of the setup, or how it works you can read that on their documentation, but you can see how declarative the below config is. Once I setup the Route53 hosted zone, see how simple it is to set the domainName, it does everything else for you.

{
  config() {
    return {
      stage: 'dev',
      name: 'thomblweed-client',
      region: 'eu-west-2',
      cdk: {
        fileAssetsBucketName: 'thomblweed-cdk-toolkit'
      }
    };
  },
  stacks(app) {
    app.setDefaultFunctionProps({
      runtime: 'nodejs20.x'
    });
    app.stack(function Site({ stack }) {
      const site = new RemixSite(stack, 'site', {
        customDomain: {
          domainName: 'thomblweed.dev'
        },
        buildCommand: 'pnpm build',
        path: '.',
        runtime: 'nodejs20.x',
        edge: false,
        environment: {
          SUPABASE_URL: process.env.SUPABASE_URL || '',
          SUPABASE_ANON_KEY: process.env.SUPABASE_ANON_KEY || '',
          SUPABASE_COOKIE_DOMAIN: process.env.SUPABASE_COOKIE_DOMAIN || ''
        }
      });
      stack.addOutputs({
        url: site.url
      });
    });
    if (app.stage !== 'prod') {
      app.setDefaultRemovalPolicy('destroy');
    }
  }
} satisfies SSTConfig;

In the couple of months since deploying this site I have had zero issues, and my costs have totalled to around £1.60 per month so far.