If you have visited this site pre February 2022 you may have noticed some slight UI tweaks here and there. The reality is I have completely rewritten the site, moving away from the well-loved Next.js to Remix. I'm not going to go into tonnes of detail here but I thought it made sense to cover some of the reason why I made the move and some of the new technologies I am using.
First things first, I want to clarify here that Next is a great framework and you can build some incredibly impressive things with it. A recent great example I've come across is Brian Lovin's site which is built in Next, server-side renders content and uses graphQL and Apollo for retrieving and caching data (this is an over simplification for sure, but you get the idea). His site is open source so you can have a peek, you'll definitely learn some things a long the way.
However, for me it all came back to the question:
What do I need to be able to do on my site?. So I tried to simplify my answer into some actionable points:
In addition to this there also some very important factors when it comes to the app and the code itself:
stale-while revalidateheader which gives you the same caching behaviour as Next's ISR.
linksexport or use something like Tailwind (or UnoCSS in my case).
Of course you could debate that a lot of the above or similar could be achieved with Next in some shape or form. The biggie for me though was Forms: how we submit and handle the data and how that data is then pushed to the UI. I have around 14 different forms in the admin for this site to add, edit and delete content which is a fair amount generally speaking. Tackling this with Next, onSubmit and API routes seemed like an incredibly daunting task and I know I would inevitably end up confusing myself ("OK so I'm submitting the form, which API route am I hitting again? Hmm, where did I put that file? I'm pretty sure that's the right path..."). With Remix I don't need to think about that, everything I need is in a single file, which I love.
Moving over from Next to Remix I made the decision to move all of my content over to a database rather than keeping it in Notion. The main reason here being I wanted to create a mini CMS for myself where I can edit the content "in-site" rather than opening a separate app. There's a few reasons for this:
To store all of the data I decided to go with Planetscale. I looked at quite a few different options but at the time there was a lot of hype about them on Twitter and they have a really generous free tier, perfect for my use case and experimenting. Now I needed a way to interact with my database...
Prisma is a
Prisma db pushcommand. This also generates the Prisma Client for you, so when we're writing our queries Typescript automagically knows what's available to use (thanks to our schema)
prismawhich we use for our queries.
actionsin this case) and return data.
A couple of good tips when querying your data:
takequery option to get the number of items you need
selectquery option to get the fields that you need
includequery option if you have any relations you'd also like to add. (e.g a User might have some Posts, where Posts is a separate model but associated to a User ID).
This is a great practice to follow because the less time we spend processing the fetched data the quicker we can get that data back to the client, and by sending a smaller payload we can keep our back-end fast and our page loads snappy.
In reality, we don't want to be hitting our database on every request, so there tends to be a cache layer which sits between the database and the back-end. In my case I'm using Upstash for this.
Originally I was playing with the idea of invalidating Vercels CDN cache so I could purge URL's as and when I needed, but that came to no avail (although this could be an option in the future based off of Next 12.1's on-demand Incremental Static Regeneration).
Instead, I needed to look at an external service for my caching needs. What I needed was a key value store which was simple to use, worked nicely with serverless functions and was quick. After coming across a thread on twitter I decided to give Upstash a whirl.
What's great about Upstash is that rather than dealing with connection pooling they have the option to use their REST API, which is perfect for serverless sites. This means I could create some simple
del methods (which are essentially the same fetch request with some slight changes) and Upstash deals with the rest.
Now when I'm requesting data I can:
It's been a great addition to the stack but in the future I'd love to completely negate this step by dealing with the CDN cache directly.
When rewriting the site I wanted to rethink the way I approached styles. I used a mixture of CSS-in-JS and styled-jsx in my Next site but for Remix I wanted to keep it simple, understandable and performant. I was initially going to use Tailwind but then I came across UnoCSS by @antfu7. At it's core UnoCSS is an atomic CSS generator where you supply you're preferred "library" (Tailwind, WindiCSS etc) via presets and have the option to customise it however you like. It's incredibly quick and available as a plug-in for a lot of frameworks. I used the CLI for my Remix rewrite and it works great! I supply it with a couple of glob patterns for the files I want to watch and UnoCSS does the rest for me based off of my config.
It is worth noting that it did take me a while to get used to all of the different class names, but once you pick it up you find yourself creating interfaces quicker than ever.
Update 10.03.22: After some interest in how I use UnoCSS with Remix on Twitter and Discord I've written a follow up post using UnoCSS with Remix
Rewriting this site did take a lot of effort and a lot of work to get into a good place. However, I do think it has really paid off and I'm happy with the result. Even if you're not fully convinced by what I've written above I definitely recommend you give Remix a go!
In terms of the site itself, if you have any feedback please feel free to tweet me and share it with anyone you think will benefit.