How to migrate your website from Nuxt.js to Astro

Lokman Musliu Founder and CEO of Lucky Media
Lokman Musliu

September 25, 2025 · 5 min read

How to migrate your website from Nuxt.js to Astro

Migrating frameworks can feel a bit like moving houses: you’ve got to pack everything up, figure out where it’s going to live in the new place, and pray you don’t discover an old pizza slice under the couch during the move. In this guide, we’re going to walk through migrating your Nuxt 4 marketing site to Astro step by step.

We’ll cover the key differences between the two frameworks, demonstrate code examples from both sides, and lay out best practices for making the journey smooth. Whether you’re doing this migration to gain the shiny performance benefits of Astro or because you just like a good challenge, this post has you covered.

Why Migrate from Nuxt 4 to Astro?

Nuxt is fantastic if you’re building complex web apps; it gives you deep Vue integration plus SSR and routing magic. But for a marketing site? That’s where Astro shines. Astro generates most of your site as static HTML (with dynamic enhancements as needed), which means lightning-fast load times, drastically reduced JavaScript payloads, and happy SEO bots.

Why this matters for marketing sites:

  • Faster performance → better conversions.

  • Easier to integrate CMS or content APIs.

  • Simplified SEO management.

  • Astro’s “islands architecture” reduces unnecessary JavaScript.

If your Nuxt marketing site feels a little too heavy, Astro is like a fresh minimalist apartment: all the essentials, zero clutter.

Astro vs Nuxt comparison

Astro vs. Nuxt

Before packing your virtual moving boxes, let’s review the difference in philosophy:

  • Nuxt 4: Full-stack web application framework powered by Vue. Great for SPAs and SSR. Focused on feature-rich apps.

  • Astro: Primarily a static site generator with optional server-side rendering. Ships “0 JavaScript by default.” Perfect for content-driven sites.

Think of Nuxt as a Swiss Army knife; it has every tool imaginable, even ones you may never use. Astro is more like a laser-focused scalpel: optimized for slicing web performance problems into tiny pieces.

We have written a detailed comparison between Nuxt and Astro.

Routing Differences and Migration Strategy

Both Nuxt and Astro use file-based routing. But the devil, as always, is in the details.

Nuxt

  • pages/about.vue/about

  • pages/users/[id].vue/users/:id

Nuxt uses Vue Router under the hood. Example:

<!-- Nuxt dynamic page -->
<template>
  <h1>User: {{ route.params.id }}</h1>
</template>

<script setup>
import { useRoute } from 'vue-router';
const route = useRoute();
</script>

Astro

Astro uses src/pages/ and getStaticPaths() for dynamic content:

<!-- src/pages/users/[id].astro -->
---
export async function getStaticPaths() {
  const users = [{id:'1'}, {id:'2'}];
  return users.map(user => ({
    params: { id: user.id },
    props: { user },
  }));
}
const { user } = Astro.props;
---
<h1>User ID: {user.id}</h1>

Migration Tip:

For each Nuxt dynamic route (pages/users/[id].vue), create an Astro equivalent with a getStaticPaths() function. If your site relies heavily on API-driven dynamic content, start by identifying which sections can be pre-rendered and which require SSR.

Astro uses zero Javascript by default

Data Fetching

From useFetch to Astro’s Server-First Model

Nuxt

Nuxt has useFetch and useAsyncData built to automatically sync with SSR and hydration.

<script setup>
const { data: posts } = await useAsyncData('blog', () => $fetch('/api/posts'));
</script>

Astro

Astro favors fetch() in frontmatter, which executes during build or SSR:

---
const response = await fetch('https://api.example.com/posts');
const posts = await response.json();
---
<ul>
  {posts.map(post => <li>{post.title}</li>)}
</ul>

Migration Shortcut:

Replace useFetch calls with plain fetch inside Astro frontmatter. Bonus points: no Nuxt hydration logic needed because Astro already pushes everything into static HTML.

Component Architecture and Interactivity

Nuxt

  • Vue components, auto-imported globally.

  • <NuxtIsland> for partial hydration.

Astro

  • .astro components are static by default.

  • For interactivity, bring in a framework component (React/Vue/Svelte/etc.) and hydrate it with a client directive.

---
import { InteractiveButton } from '@/components/InteractiveButton.jsx'
---

<InteractiveButton client:visible>Click!</InteractiveButton>

This fine-grained hydration means you can sprinkle interactivity without dragging down performance. Imagine your hero slider can stay interactive while the rest of the page is pure HTML.

Nuxt is ideal for building user centric apps

SEO & Meta Tag Strategies for Marketing Sites

SEO will make or break your marketing site migration.

Nuxt

useSeoMeta({
  title: 'My Site',
  description: 'Awesome product info',
});

Astro

---
const { title, description } = Astro.props
---

<head>
  <title>{title}</title>
  <meta name="description" content={description} />
</head>

No abstraction, just plain <meta> tags. Combine Astro layouts with props to DRY out repeated tags (title, og:image, etc.).

Middleware: Auth and Redirects

Nuxt

Custom middlewares are defined in middleware/auth.js.

Astro

Astro middleware lives in src/middleware.js and uses defineMiddleware.

// src/middleware.ts
import { defineMiddleware } from "astro:middleware";

export const onRequest = defineMiddleware( (ctx, next) => {
    if (! ctx.cookies.get("auth")) {
        return Response.redirect("/login")
    }

    return next();
});

Migration Note:

Astro middleware runs only on the server. Unlike Nuxt, there’s no client-side hook equivalent. Great for protecting marketing/admin pages.

Astro works with React Vue Preact Svelte

Plugins vs. Integrations

Nuxt has a dedicated plugin system:

export default defineNuxtPlugin(nuxtApp => {
  nuxtApp.provide('sayHi', () => console.log("👋 Hello"));
});

Astro does not. Instead:

  • Use integrations for framework-level additions (React, Tailwind, Svelte).

  • Use utility modules for reusable functions.

  • Inline <script is:inline> for lightweight client-side utilities.

Migration Hint:

If you had Nuxt plugins for analytics, just move them to a <script> tag or Astro integration.

Layouts and Consistent Page Structure

Both frameworks support layouts with <slot />.

Nuxt

  • Defined in /layouts/default.vue.

Astro

  • Defined in /src/layouts/Layout.astro.

Big difference: Astro uses props passed down during rendering; no directive like definePageMeta.

Astro Partner Agency

Common Mistakes

  • Assuming auto-imports exist in Astro

    ➝ Explicit imports required.

  • Forgetting client directives

    ➝ Without client:load or client:visible, your React/Vue component won’t hydrate.

  • Losing middleware on the client

    ➝ Astro middleware is server-only.

Migration Tips

Migration approach we would recommend:

  1. Audit your Nuxt site: Which pages are static vs. interactive?

  2. Start with static pages: About, pricing, landing pages → easiest wins in Astro.

  3. Handle dynamic content with getStaticPaths: Blog posts, product pages.

  4. Add interactivity selectively: Navigation menus, forms, or modals only when essential.

  5. Test middleware early: Make sure your redirects/auth pipelines survive the move.

Migrating feels like less of a “we’re moving houses” situation and more like “we’re decluttering and moving into a streamlined loft.” You’ll thank yourself when your marketing site loads in under a second.

Why Astro for static websites

Conclusion

Migrating from Nuxt 4 to Astro is a rewarding exercise. You keep all the power of your original content-driven app but shed the extra JavaScript baggage. If you’re chasing that “green Lighthouse score,” Astro is basically cheat mode.


Let's chat!

If you need help migrating a Nuxt website to Astro, let's get in touch.

Lucky Media is proud to be recognized as a leading software development agency!

FAQs

Do I need to rewrite all my Vue components for Astro?

Not at all! Astro supports multiple frameworks. You can actually import .vue components directly (with @astrojs/vue integration). This allows you to migrate gradually.

What about CMS integrations? My Nuxt site uses Contentful/Strapi.

Astro works beautifully with a headless CMS. Use fetch() or SDKs inside frontmatter to pull CMS data. Most CMS integration examples exist in Astro’s docs. We have written a detailed article that shows the combination of a Headless CMS and Astro and how to build a page builder with Astro and Contentful.

Can Astro handle SSR like Nuxt does?

Yes. Astro defaults to static, but if you need SSR (e.g., authenticated dashboards), you can enable SSR mode in astro.config.mjs. You can also have a mix of both, static pages and SSR.

How do I migrate Nuxt middleware like auth to Astro?

Move core logic (checking tokens, session validity) into src/middleware.js. Remember, it executes server-side only. If you relied on client-side route blocks, you’ll need explicit in-page guards now.

What are the performance benefits when moving from Nuxt to Astro?

Huge. By stripping away unused JavaScript, Astro sites often score 90+ in Lighthouse “Performance” and load noticeably faster. For marketing sites, this directly translates into higher SEO rankings and conversions.

Technologies

Astro
Lokman Musliu Founder and CEO of Lucky Media
Lokman Musliu

Founder and CEO of Lucky Media

Stay up-to-date

Be updated with all news, products and tips we share!

Let’s chat

We partner with a limited number of brands each quarter to ensure senior-level attention on every project.

lokman and arlind headshots
Teamwork

Related posts

March 21, 2025

How to maintain enterprise websites
Statamic
Business