Rewriting my website in Svelte

${ Yet another rewrite of my blog 😅 }
2025-05-05

👋

I’m publishing this at the same I release a complete rewrite of my website. Yet another one to add to the list of redesigns I’ve done!

The journey started a few months ago when I was wondering about two things:

  1. How could I build a kind of CMS to make publishing easier?
  2. Since I’m loving Svelte, could I build my site with it?

I’d moved the site to 11ty (a great static site generator!) a couple of years ago. And I was happy with it, but over the years there were a couple of things that bothered me.

First, like other static site generators, content is stored as markdown files in the same repo as the code. I felt this made writing a new post, or even just fixing a typo, a “big deal” - create a branch, check out the code, make the change, commit the changed files, git push, open a PR, wait for the build, merge the PR.

This is why I was considering building a CMS. I imagined something that would integrate with the Gitlab repository, read the content files, and automate away all the complexity of making these changes. It was pretty tempting. But it felt unnecessarily complex.

So I thought “why not store the content in a DB somewhere and then pull in the content during the build?”

The second issue I had with 11ty was that, while it is very flexible, it was a different language to everything else I was doing. Any cool things I learnt about Svelte couldn’t be easily carried over to the site. And since I only occasionally changed the site code, each time I wanted to make a change I had to re-learn how 11ty works.

My site also had very little client-side JS, so there was a big barrier to adding any interactivity or cool features to the site.

So after some experimentation, I pulled the trigger and started a complete rewrite of the site 🙌

(I could have kept the same design but, of course, I decided to redo that as well 😅)

So how does it work?

The principle is pretty straight-forward:

  1. I’m running a PocketBase instance as my “backend”. This is where I store all my content.
  2. The Svelte site is configured to pre-render everything during build. This turns the build assets into a static site I can host without any server-side processing - just a bunch of HTML, CSS, and JS files.
  3. The build process pulls data from the PocketBase backend to populate all the pages with content.
    • I’m using Gitlab’s CI/CD pipeline to run this build
  4. That’s about it 🤷

PocketBase stores all my posts, projects, images, and even page titles. This will allow me later, if I want, to “easily” build a CMS on top of it to edit content.

Screenshot of the table and editor in PocketBase that store the content for my blog posts

I love PocketBase because:

  • I can host it myself very easily
  • I have a nice admin UI where I can edit content
  • Gives me all the features I need (APIs, auth, file storage, etc) and a simple JS library to access my data

I also tried to use Appwrite for my backend, but I really struggled because I wasn’t enjoying working with it. I’m not sure why. I think I just didn’t enjoy the UI that much 🤷

In terms of the actual build, Svelte makes it pretty simple:

  1. Add export const prerender = true to the root +layout.js file to have it pre-render everything
  2. Make extensive use of load functions in +page.server.ts files to fetch all the data I need during the build and provide that to the actual page code

On the actual pages I base everything off the data that comes back from the load function and that hardcodes the content into the generated HTML files.

A nice feature I didn’t expect is that when I run the site in dev mode (npm run dev) I can just refresh the page and it gets the latest content from PocketBase 😮

When running in dev mode it isn’t actually pre-rendering anything - everything is dynamic. This made testing things so much easier!

But I can still use regular Svelte code on any of the pages for things I want to be dynamic and rendered on the client-side. So I get the best of both worlds!

This is how I implemented some basic search functionality on the posts and projects pages!


Images were not going to be part of the initial release, but in the end I decided to spend some time adding basic support for them. I figured it wouldn’t be that hard. So the current solution isn’t quite ideal, but works.

  • PocketBase has a table with all my images - plus the image alt-text and some other metadata
  • I wrote a little script to fetch all the rows in that table and download each image into a folder
    • This is run before the build to get all the images the site needs
    • Files are named after their database ID (so I don’t have to worry about file names!)
  • Everywhere I want to use an image (in posts, as a social preview, as a project logo) I do so by referencing the image ID in the database
    • Something like {{image/<id>}}
  • During the build each of these references is replaced with the path to the file that was downloaded by the script (and adds any other metadata it needs - e.g. alt text)

I will probably improve this at some point, but it works well for now!

What next?

This was a complete rewrite, and I decided to publish the new version before I considered it perfect. So there are still some rough edges and plenty of new (and old) things I want to add.

One completely new feature I really want to add is a Bluesky integration to allow people to leave comments and likes on my posts/projects. I always love seeing that on other people’s blogs!

Here is an example (from ashley.dev ):

Screenshot of bluesky interaction section from ashley.dev's website showing like counter, users who liked, as well as comments.

I also want to add some different themes. Right now there is only a dark theme. I’ve already set up the CSS classes to support basic theming, so hopefully it will be relatively easy 🤞

I’ll probably set up a system to generate unique social preview images for each post. I have an idea on how to achieve that without much work, so that would be nice.

When I set up PocketBase I added support for adding tags to posts & projects, but now that I’ve added basic search, I’m not sure if it makes sense. Maybe I’ll try something different.

And there will always be little tweaks here and there!


So that’s the story of the new version of my website, it was a lot of fun!

Plus, now that I’ve broken free of the constraints created by static site generators I feel I can build anything here. I’m looking forward to it! 🙌

// the end