Nuxt 4 in 2026: Neue Verzeichnisstruktur und Migration von Nuxt 3

Nuxt 4 bringt eine neue app/-Verzeichnisstruktur, verbessertes Data-Fetching, Shallow Reactivity und Unhead v2. Kompletter Migrationsleitfaden von Nuxt 3 mit Codemod-Automatisierung.

Nuxt 4 Verzeichnisstruktur und Migrationsleitfaden von Nuxt 3 mit Codebeispielen

Nuxt 4 markiert einen bedeutenden Meilenstein in der Entwicklung des Vue.js-Meta-Frameworks. Mit einer grundlegend überarbeiteten Verzeichnisstruktur, verbesserter TypeScript-Integration und optimiertem Data-Fetching setzt das Release neue Standards für die moderne Webentwicklung. Dieser Artikel beleuchtet die wichtigsten Änderungen in Nuxt 4, erklärt die neue Projektstruktur im Detail und zeigt den konkreten Migrationspfad von Nuxt 3 auf.

Automatisierte Migration verfügbar

Nuxt 4 führt eine neue app/-Verzeichnisstruktur ein, die Client- und Server-Code klar voneinander trennt. Die Migration kann schrittweise erfolgen — ein offizieller Codemod automatisiert den Großteil der Umstellung.

Die neue Verzeichnisstruktur in Nuxt 4

Die auffälligste Neuerung in Nuxt 4 betrifft die Projektstruktur. Während in Nuxt 3 sämtliche Verzeichnisse wie components/, pages/ und composables/ direkt im Projektstamm lagen, führt Nuxt 4 ein dediziertes app/-Verzeichnis ein. Diese Änderung schafft eine klare Trennung zwischen clientseitigem Anwendungscode, serverseitigem Code und geteilten Ressourcen.

text
my-nuxt-app/
├─ app/
│  ├─ assets/
│  ├─ components/
│  ├─ composables/
│  ├─ layouts/
│  ├─ middleware/
│  ├─ pages/
│  ├─ plugins/
│  ├─ utils/
│  ├─ app.vue
│  ├─ app.config.ts
│  └─ error.vue
├─ content/
├─ public/
├─ shared/
├─ server/
└─ nuxt.config.ts

Das app/-Verzeichnis enthält nun alles, was zur clientseitigen Anwendung gehört — von Komponenten über Composables bis hin zu Seiten und Layouts. Das server/-Verzeichnis bleibt an seiner bisherigen Position und beherbergt API-Routen, Server-Middleware und Datenbanklogik. Neu hinzugekommen ist das shared/-Verzeichnis, das Code aufnimmt, der sowohl auf dem Client als auch auf dem Server verwendet wird — etwa gemeinsame TypeScript-Typen, Validierungsschemas oder Hilfsfunktionen.

Diese Reorganisation bringt mehrere Vorteile mit sich. Die Projektstruktur wird übersichtlicher, besonders bei größeren Anwendungen. Die klare Trennung der Zuständigkeiten erleichtert die Zusammenarbeit in Teams und reduziert das Risiko, versehentlich serverseitigen Code im Client-Bundle auszuliefern. Darüber hinaus ermöglicht sie eine präzisere TypeScript-Konfiguration, da Client- und Server-Code nun eigene tsconfig-Dateien erhalten.

Migration von Nuxt 3: Der konkrete Ablauf

Die Migration eines bestehenden Nuxt-3-Projekts auf die neue Struktur lässt sich in wenigen Schritten durchführen. Zunächst sollte die Nuxt-Version aktualisiert werden:

bash
npx nuxt upgrade --dedupe

Anschließend steht ein offizieller Codemod zur Verfügung, der die Dateien automatisch in die neue Verzeichnisstruktur verschiebt:

bash
npx codemod@latest nuxt/4/file-structure

Dieser Codemod analysiert die bestehende Projektstruktur und verschiebt Verzeichnisse wie components/, pages/, composables/, layouts/, middleware/, plugins/ und utils/ in das neue app/-Verzeichnis. Auch Dateien wie app.vue, error.vue und app.config.ts werden korrekt umplatziert.

Für Projekte, die eine schrittweise Migration bevorzugen oder die bisherige Struktur vorübergehend beibehalten möchten, bietet die Nuxt-Konfiguration eine Kompatibilitätsoption:

nuxt.config.tstypescript
export default defineNuxtConfig({
  srcDir: '.',
  dir: { app: 'app' },
})

Mit dieser Konfiguration lässt sich steuern, wo Nuxt nach den Anwendungsdateien sucht. Das ermöglicht eine graduelle Migration, bei der einzelne Verzeichnisse nacheinander in die neue Struktur überführt werden.

Verbessertes Data-Fetching mit getCachedData

Nuxt 4 erweitert die Data-Fetching-APIs um leistungsfähigere Caching-Mechanismen. Die Funktion getCachedData erhält einen zusätzlichen Kontextparameter, der Informationen über den Auslöser des Datenabrufs bereitstellt. Damit lässt sich differenziert steuern, wann gecachte Daten verwendet und wann frische Daten vom Server geholt werden sollen.

app/composables/useProductData.tstypescript
export function useProductData(productId: string) {
  return useAsyncData(
    `product-${productId}`,
    () => $fetch(`/api/products/${productId}`),
    {
      getCachedData: (key, nuxtApp, ctx) => {
        if (ctx.cause === 'refresh:manual') return undefined
        return nuxtApp.payload.data[key]
      },
    },
  )
}

In diesem Beispiel wird bei einer manuellen Aktualisierung (etwa durch einen Button-Klick) stets ein neuer Serveraufruf durchgeführt, während bei Navigation oder Hydration die gecachten Daten verwendet werden. Dieses Muster verbessert die Performance erheblich, da unnötige Netzwerkanfragen vermieden werden, ohne dass die Möglichkeit zur gezielten Datenaktualisierung verloren geht.

Für Entwicklungsteams, die sich auf Vue/Nuxt-Interviewfragen vorbereiten, ist das Verständnis dieser Caching-Strategien ein wesentlicher Baustein.

Shallow Reactivity als Standard

Eine der technisch bedeutsamsten Änderungen in Nuxt 4 betrifft das Reaktivitätssystem. Die Rückgabewerte von useFetch und useAsyncData verwenden nun standardmäßig flache Reaktivität (Shallow Reactivity) anstelle der bisherigen tiefen Reaktivität. Das bedeutet, dass nur Änderungen am Wurzelobjekt — also das Ersetzen des gesamten .value — reaktive Updates auslösen.

app/pages/dashboard.vuetypescript
<script setup lang="ts">
const { data: metrics } = await useFetch('/api/dashboard/metrics')
metrics.value = { ...metrics.value, visits: 100 }
const { data: settings } = await useFetch('/api/settings', {
  deep: true,
})
</script>

Bei der Arbeit mit metrics muss das gesamte Objekt ersetzt werden, anstatt einzelne verschachtelte Eigenschaften zu ändern. Wer das bisherige Verhalten benötigt — etwa bei komplexen, tief verschachtelten Datenstrukturen — kann die Option deep: true explizit setzen.

Diese Umstellung bringt spürbare Performance-Verbesserungen, da Vue weniger Proxy-Objekte erstellen und verwalten muss. Besonders bei großen Datensätzen, wie sie typischerweise in Dashboard-Anwendungen oder Datentabellen vorkommen, macht sich der Unterschied bemerkbar. Das Konzept der flachen Reaktivität reduziert den Speicherverbrauch und beschleunigt das Rendering.

Überarbeitete TypeScript-Konfiguration

Nuxt 4 überarbeitet die TypeScript-Konfiguration grundlegend. Die generierte tsconfig.json verwendet nun Project References, um Client-, Server- und Shared-Code mit jeweils eigenen Typkonfigurationen auszustatten. Die Datei im Projektstamm dient dabei als Referenzpunkt:

json
{
  "files": [],
  "references": [
    { "path": "./.nuxt/tsconfig.app.json" },
    { "path": "./.nuxt/tsconfig.server.json" },
    { "path": "./.nuxt/tsconfig.shared.json" },
    { "path": "./.nuxt/tsconfig.node.json" }
  ]
}

Jede Referenz zeigt auf eine spezifische Konfiguration, die Nuxt automatisch im .nuxt/-Verzeichnis generiert. So erhält der Client-Code andere Typ-Definitionen als der Server-Code, was zu präziseren Typprüfungen und besserer IDE-Unterstützung führt. Ein Server-Utility, das Node.js-APIs verwendet, löst im Client-Code nun korrekt einen Typfehler aus, anstatt stillschweigend akzeptiert zu werden.

Die Typprüfung für das gesamte Projekt erfolgt mit einem angepassten Befehl:

bash
nuxt prepare && vue-tsc -b --noEmit

Der Parameter -b aktiviert den Build-Modus von vue-tsc, der die Project References korrekt auflöst. Das Ergebnis ist eine vollständige Typprüfung über alle Bereiche der Anwendung hinweg — Client, Server und Shared — mit jeweils passenden Typ-Definitionen.

Bereit für deine Vue.js / Nuxt.js-Interviews?

Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.

Optimiertes KeepAlive-Verhalten

Das Caching von Seitenkomponenten über die keepalive-Eigenschaft wurde in Nuxt 4 optimiert. Die Konfiguration erfolgt nun direkt über die <NuxtPage>-Komponente und erlaubt eine granulare Steuerung, welche Komponenten im Speicher gehalten werden sollen:

vue
<!-- app/pages/dashboard.vue -->
<template>
  <NuxtPage :keepalive="{
    include: ['DashboardMetricsCard', 'DashboardRecentActivity'],
  }" />
</template>

Durch die explizite Angabe der zu cachenden Komponenten über include lässt sich der Speicherverbrauch kontrollieren. Nur die benannten Komponenten werden beim Seitenwechsel im Speicher gehalten und bei Rückkehr ohne erneutes Rendering wiederhergestellt. Alle anderen Komponenten werden wie gewohnt zerstört und bei Bedarf neu erstellt.

Wer tiefer in die Rendering-Strategien von Nuxt eintauchen möchte, findet im SSR- und Static-Generation-Leitfaden weiterführende Informationen zu serverseitigem Rendering und statischer Generierung.

Unhead v2: Modernes SEO-Management

Nuxt 4 integriert Unhead v2, die nächste Generation der Head-Management-Bibliothek. Die API bleibt weitgehend kompatibel, erhält aber wichtige Verbesserungen. Reactive Getter (Funktionen statt statischer Werte) werden nun als bevorzugtes Muster für dynamische Meta-Daten eingesetzt:

app/pages/product/[id].vuetypescript
<script setup lang="ts">
const route = useRoute()
const { data: product } = await useFetch(`/api/products/${route.params.id}`)
useSeoMeta({
  title: () => product.value?.name ?? 'Product',
  ogTitle: () => product.value?.name ?? 'Product',
  description: () => product.value?.description ?? '',
  ogImage: () => product.value?.imageUrl ?? '',
})
</script>

Durch die Verwendung von Getter-Funktionen aktualisieren sich die Meta-Tags automatisch, sobald sich die zugrundeliegenden Daten ändern — ohne dass ein manueller Watcher eingerichtet werden muss. Das vereinfacht den Code und verhindert veraltete Meta-Informationen.

Ein wesentlicher Unterschied zu Nuxt 3 betrifft den Plugin-Umfang. Unhead v2 liefert nur noch die Kern-Funktionalität aus und stellt erweiterte Features als opt-in Plugins bereit. Wer Template-Parameter oder benutzerdefiniertes Tag-Sorting benötigt, registriert die entsprechenden Plugins explizit:

app/plugins/unhead.tstypescript
import { TemplateParamsPlugin, AliasSortingPlugin } from '@unhead/vue/plugins'
export default defineNuxtPlugin({
  setup() {
    const unhead = injectHead()
    unhead.use(TemplateParamsPlugin)
    unhead.use(AliasSortingPlugin)
  },
})

Diese Modularisierung reduziert die Bundle-Größe für Anwendungen, die keine erweiterten Head-Management-Funktionen benötigen.

Weitere Breaking Changes im Überblick

Neben den hier detailliert besprochenen Änderungen bringt Nuxt 4 eine Reihe weiterer Anpassungen mit sich, die bei der Migration beachtet werden sollten. Die Standardwerte einiger Konfigurationsoptionen haben sich geändert — etwa ist scanPageMeta nun standardmäßig aktiviert, und die Route-Normalisierung entfernt abschließende Schrägstriche. Einige experimentelle Features aus Nuxt 3 sind in Nuxt 4 zum stabilen Standard geworden und erfordern keine explizite Aktivierung mehr.

Die Build-Ausgabe wurde ebenfalls optimiert. Nuxt 4 erzeugt kleinere Bundles durch verbessertes Tree-Shaking und die bereits erwähnte Modularisierung von Unhead. Die Serverstart-Zeiten profitieren von der klareren Projektstruktur, da Nuxt weniger Verzeichnisse scannen muss.

Für die automatisierte Migration empfiehlt sich eine Checkliste: Nach dem Ausführen des Codemods sollten alle Import-Pfade überprüft, die TypeScript-Konfiguration regeneriert (nuxt prepare), die Test-Suite ausgeführt und die Anwendung manuell in den kritischen Bereichen getestet werden.

Nuxt-3-Support-Zeitplan

Nuxt 3 erhält weiterhin Sicherheitsupdates und kritische Bugfixes bis zum 31. Juli 2026. Nach diesem Datum wird Nuxt 3 nicht mehr unterstützt. Eine rechtzeitige Planung der Migration vermeidet den Betrieb von Produktionsanwendungen auf einem nicht mehr unterstützten Framework.

Fazit und Ausblick

Nuxt 4 stellt eine durchdachte Evolution des Frameworks dar, die den Fokus auf Entwicklerproduktivität, Performance und Wartbarkeit legt. Die neue Verzeichnisstruktur mit dem app/-Verzeichnis schafft Ordnung in wachsenden Projekten, während die überarbeitete TypeScript-Integration mit Project References für präzisere Typensicherheit sorgt. Die Verbesserungen beim Data-Fetching und der Wechsel zu Shallow Reactivity bringen messbare Performance-Gewinne.

Der Migrationspfad von Nuxt 3 ist klar definiert und durch den offiziellen Codemod weitgehend automatisiert. Für bestehende Projekte empfiehlt sich ein schrittweises Vorgehen: zunächst das Upgrade der Abhängigkeiten, dann die Umstrukturierung der Verzeichnisse und schließlich die Anpassung an die neuen API-Standardwerte. Die Kompatibilitätsoptionen in der Nuxt-Konfiguration ermöglichen dabei einen fließenden Übergang ohne sofortige Umstellung aller Projektbereiche.

Fang an zu üben!

Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.

Tags

#nuxt
#vue
#migration
#typescript
#tutorial

Teilen

Verwandte Artikel