January 20th 2025

Meet my new Astro blog, same as the old Nuxt blog

This blog was created with Nuxt 2 seven years ago and served me well but in that time I have been working professionally with vanilla Javascript/Typescript, Vue, and now React. I have also been playing around with Svelte and Solid.js. Given my desire to constantly be learning and experimenting with new technologies it seemed time to use a static-site generator that would accommodate all of the above… Enter Astro! So welcome to my mostly-the-same-looking site that is now completely different!

Same same, buf different...

Astro is a static site generator that allows you to use multiple frontend component frameworks within the same project, or even page, by turning the various sections of your page into interactive islands. It can server-render these components or allow you to bundle them into your page for client-side interactivity. It also includes its own server-rendered Astro components which are great for basic functionality and page layouts. Finally, it has a concept of Content Collections which allows me to continue writing my posts in Markdown and aggregate them simply for my index and tag specific pages.

The process

Todoist list
Todoist list

The steps I had to go through went something like this:

Some additional things I did since I was already deep into the refactoring groove:

Some things I got for basically free

Since this is now an Astro site no-longer using my dated and custom webpack plugin that was coupled to Nuxt 2 I am now able to use some out-of-the-box features that Astro provides to create things such as:

  • A sitemap
  • An RSS feed
  • Automatically optimized images
  • Custom images for article previews and sharing (not really a specific feature, but dead-simple with Astro’s content collections). Compare and contrast
  • The ability to have pages that can run basically any type of frontend framework. (Expect some blog pages with React components coming soon!)
  • A bug-free build and mostly-painless upgrade experience. My webpack plugin for generating my Nuxt content worked, however it had some annoying bugs… I was stuck sometimes needing to build multiple times because of a webpack loader race-condition that I never took the time to solve; and it was coupled pretty heavily to Nuxt 2 since it modified Nuxt’s generated code to inject meta content into rendered pages. The plugin was the main reason I never upgraded to Vue 3, Nuxt 3, or Vite.

Thinking in Astro

The biggest mind-shift and friction with this refactor is changing my thinking around how I handle javascript in my static rendered components. Component instances all share a single run of their <script /> tags which doesn’t always seem intuitive. So make sure you remember the common patterns linked above, use a web component if you need to run instance-specific code in the browser, and realize there will be a strong boundary between server and browser code (ultimately a good tradeoff that still includes some ways to cross the boundary when needed).

The biggest gotcha that I kept running into is including components (both Astro or other) and having them do nothing with no errors. If that happens consider where the code is running (server, browser, frontmatter, astro component, web component, etc) and remember that you may need client directives to accomplish some of your component’s goals.

Things I still have to do

There is one thing I still need to do to call this refactor a complete success, and that is to add back offline support to my PWA tools. I was using Nuxt-PWA, but I am obviously not using that anymore. But even with Nuxt-PWA and Workbox I had bugs that I only became aware of after-the-fact when I would push updates… It turns out caching only a portion of your site’s hashed assets is kind of complicated when your site is built as a whole package. So I’ll figure that problem out (I will probably be utilizing PNPM to build my Tools pages separately so they can be cached as a whole) and maybe even write about how I solved it.

Thanks for checking my new site out, I hope you like it!

<view-source on="" />