5 min read
Migrating from Nuxt to Astro

When Astro 5 dropped, I knew I wanted to try it. My old site, built with Nuxt 3, had been working fine - it handled static and dynamic content well enough. But for a site like mine that’s mostly static, Astro seemed like a better fit. I gave it a shot and spoiler: I’m sticking with it.

Number 5
Astro 5 is alive

Starting with a Theme

To save time, I started with a free theme: Astro Nano. It’s clean and minimal, and I didn’t feel like it would fight me when I started customizing it. Most of the changes I made were cosmetic or structural, tweaking the design to match the feel of my site better. The process was straightforward, and Astro’s component-based system made adjusting things as I went easy.

Adding Animations with Tailwind and JavaScript

The theme came with simple but effective animations using Tailwind CSS classes and a small JavaScript function. Here’s how it works:

The CSS classes handle the animation styles:

.animate {
    @apply opacity-0 translate-y-3;
    @apply transition-all duration-700 ease-out;
}

.animate.show {
    @apply opacity-100 translate-y-0;
}

The JavaScript function adds the .show class to elements with the animate class, creating a staggered animation effect:

function animate() {
    const animateElements = document.querySelectorAll(".animate");

    animateElements.forEach((element, index) => {
        setTimeout(() => {
            element.classList.add("show");
        }, index * 150);
    });
}

This function is called inside an init function, which runs both on DOMContentLoaded and after Astro swaps content:

document.addEventListener("DOMContentLoaded", () => init());
document.addEventListener("astro:after-swap", () => init());

It’s lightweight, clean, and works seamlessly with Astro’s partial hydration model. These small animations add a polished feel to the site without unnecessary complexity.

Content Collections: A Game-Changer

Astro 5’s content collections were a standout feature for me. They simplify how you organize and access content. In my Nuxt site, I used an earlier version of NuxtContent, which worked, but it always needed a bit of wrangling to fit my use case.

With content collections, I can define schemas for my Markdown files. This ensures that every post, project, or snippet has the correct fields and structure. It’s type-safe and integrates well with TypeScript, so I get autocomplete and warnings if something’s off.

Here’s an example schema:

import { defineCollection, z, reference } from "astro:content";
import { glob } from "astro/loaders";

const TAGS = ["astro", "is", "coolio"];

const blog = defineCollection({
    loader: glob({ pattern: "**/*.md", base: "./src/path-to-content/blog" }),
    schema: z.object({
        title: z.string(),
        description: z.string(),
        date: z.coerce.date(),
        draft: z.boolean().optional(),
        tags: z.array(z.enum(TAGS as [string, ...string[]])).optional(),
    }),
});

export const collections = {
    blog: blogCollection,
};

This ensures that every blog post has a title, date, and the correcttags. No more worrying about typos or missing fields in my frontmatter.

Fetching the blog post data is extremely easy using the getCollection function:

import { getCollection } from "astro:content";

const data = (await getCollection("blog"))
    // Filter out draft posts
    .filter((post) => !post.data.draft)
    // Sort by date
    .sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());

Nuxt vs. Astro: When to Use What

Astro’s focus on static sites has always been its strength, but recent additions like the client router for smooth page transitions make it a solid competitor to Nuxt or Next for many use cases. However, it doesn’t come with a built-in state management store or reactivity like Vue, so you might need to add something lightweight like Nano Stores for more interactive apps. Ultimately, both tools are highly capable—choosing between them depends on your project’s needs.

Lessons Learned

  1. Start Simple: Using a theme like Astro Nano saved time and gave me a solid foundation.
  2. Content Collections Rock: Schemas in Astro’s content collections are a huge productivity boost.
  3. Animations Add Life: Small touchescan make a big difference.
  4. The Right Tool for the Job: Astro and Nuxt both have strengths; picking the right one matters.

Final Thoughts

Rebuilding my site with Astro 5 was a smooth experience, and I’m happy with the result. It’s faster, easier to maintain, and more in line with what I need from a static site generator. If you haven’t tried Astro yet, try it, especially if you’re working on a static project.