Nuxt 4 w 2026: Nowa Struktura Katalogow i Migracja z Nuxt 3
Kompletny przewodnik po Nuxt 4: nowa struktura katalogu app/, migracja krok po kroku z Nuxt 3, singleton data fetching, shallow reactivity, TypeScript context splitting, Vue Router v5, zarzadzanie meta tagami i lista kontrolna migracji.

Nuxt 4 wprowadza fundamentalne zmiany w sposobie organizacji projektow opartych na Vue. Nowa struktura katalogow z centralnym folderem app/, ujednolicona warstwa pobierania danych, domyslna plytka reaktywnosc oraz podzielony kontekst TypeScript wymagaja od zespolow programistycznych przemyslanej strategii migracji. Dla programistow pracujacych z ekosystemem Vue i Nuxt zrozumienie tych zmian jest niezbedne zarowno w codziennej pracy, jak i podczas procesow rekrutacyjnych. Niniejszy artykul omawia kazda istotna zmiane w Nuxt 4, prezentuje praktyczne przyklady kodu i dostarcza kompletna liste kontrolna migracji z Nuxt 3.
Nuxt 4 oferuje oficjalny codemod, ktory automatyzuje restrukturyzacje katalogow. Przed reczna migracja warto uruchomic npx codemod@latest nuxt/4/file-structure, aby zautomatyzowac wiekszosc zmian strukturalnych. Pozostale kroki -- takie jak dostosowanie composable'ow, konfiguracji TypeScript i zarzadzania meta tagami -- wymagaja jednak recznej interwencji.
Nowa struktura katalogu app/
Najbardziej widoczna zmiana w Nuxt 4 to przeniesienie wszystkich plikow aplikacji kliencko-serwerowej do dedykowanego katalogu app/. W Nuxt 3 komponenty, strony, layouty, middleware i pluginy znajdowaly sie bezposrednio w katalogu glownym projektu. Nuxt 4 wymusza separacje kodu aplikacji od konfiguracji, zasobow publicznych i kodu serwerowego.
my-nuxt-app/
├─ app/
│ ├─ assets/
│ ├─ components/
│ ├─ composables/
│ ├─ layouts/
│ ├─ middleware/
│ ├─ pages/
│ ├─ plugins/
│ ├─ utils/
│ ├─ app.vue
│ ├─ app.config.ts
│ └─ error.vue
├─ content/
├─ public/
├─ shared/ # New: code shared between app and server
├─ server/
└─ nuxt.config.tsNowy katalog shared/ stanowi istotne uzupelnienie architektury. Umozliwia wspoldzielenie typow, utilit i stalych miedzy kodem aplikacji (app/) a kodem serwerowym (server/). Wczesniej programisci musieli duplikowac definicje typow lub stosowac obejscia z importami wzglednymi. Katalog shared/ rozwiazuje ten problem na poziomie strukturalnym, zapewniajac jedna zrodlowa lokalizacje dla wspolnego kodu.
Plik nuxt.config.ts pozostaje w katalogu glownym projektu -- nie jest przenoszony do app/. Analogicznie, katalog server/ i public/ zachowuja swoje dotychczasowe pozycje. Ta separacja jasno definiuje granice odpowiedzialnosci: app/ zawiera kod renderowany w przegladarce i na serwerze SSR, server/ obsluguje logike backendowa, a shared/ zapewnia most miedzy tymi dwoma warstwami.
Migracja krok po kroku z Nuxt 3
Proces migracji z Nuxt 3 do Nuxt 4 sklada sie z kilku etapow. Pierwszym krokiem jest aktualizacja samego frameworka do najnowszej wersji z jednoczesna deduplikacja zaleznosci.
# Upgrade Nuxt and deduplicate dependencies
npx nuxt upgrade --dedupeNastepnie nalezy uruchomic oficjalny codemod, ktory automatycznie przeorganizuje strukture plikow zgodnie z nowym standardem. Codemod przenosi pliki do katalogu app/, aktualizuje sciezki importow i dostosowuje konfiguracje.
# Automate the directory restructuring
npx codemod@latest nuxt/4/file-structureW przypadku projektow, ktore nie moga natychmiast przejsc na nowa strukture katalogow, Nuxt 4 oferuje opcje kompatybilnosci wstecznej. Ustawienie srcDir i dir.app w konfiguracji pozwala zachowac plaska strukture podczas stopniowej migracji.
export default defineNuxtConfig({
srcDir: '.',
dir: { app: 'app' },
})Ta opcja fallback jest jednak rozwiazaniem tymczasowym. Zespol Nuxt jednoznacznie rekomenduje pelna migracje do struktury z katalogiem app/, poniewaz przyszle wersje frameworka beda optymalizowane pod katem tego ukladu. Ponadto narzedzia ekosystemu, takie jak Nuxt DevTools i moduly spolecznosci, coraz czesciej zakladaja nowa strukture jako domyslna.
Warstwa pobierania danych: singleton pattern i reaktywne klucze
Nuxt 4 wprowadza fundamentalna zmiane w dzialaniu composable'ow useAsyncData i useFetch. W Nuxt 3 wywolanie tego samego klucza danych z roznych komponentow moglo prowadzic do zduplikowanych zadan sieciowych i niespojnosci w stanie. Nuxt 4 implementuje wzorzec singleton: kazdy unikalny klucz danych jest powiazany z dokladnie jedna instancja pobierania, niezaleznie od liczby komponentow korzystajacych z tych samych danych.
Dodatkowo useAsyncData otrzymuje nowy parametr getCachedData z obiektem kontekstu ctx, ktory informuje o przyczynie ponownego wywolania. Umozliwia to precyzyjne kontrolowanie, kiedy uzywane sa dane z cache'u, a kiedy wymagane jest nowe zapytanie.
export function useProductData(productId: string) {
return useAsyncData(
`product-${productId}`,
() => $fetch(`/api/products/${productId}`),
{
getCachedData: (key, nuxtApp, ctx) => {
// ctx.cause tells why the fetch is happening
if (ctx.cause === 'refresh:manual') return undefined
return nuxtApp.payload.data[key]
},
},
)
}Parametr ctx.cause moze przyjmowac wartosci takie jak 'refresh:manual' (reczne odswiezenie przez programiste), 'refresh:hook' (odswiezenie wyzwolone przez hook cyklu zycia) czy 'navigation' (nawigacja miedzy stronami). Dzieki temu composable moze inteligentnie decydowac o strategii cache'owania: na przyklad zawsze uzywac cache'u podczas nawigacji, ale wymuszac nowe zapytanie przy recznym odswiezeniu.
Singleton pattern eliminuje rowniez problem race conditions. Gdy wiele komponentow jednoczesnie zadaje tych samych danych, Nuxt 4 wykonuje tylko jedno zapytanie i rozdziela wynik do wszystkich subskrybentow. Redukuje to obciazenie sieciowe i zapewnia spójnosc danych w calej aplikacji.
Domyslna plytka reaktywnosc (shallow reactivity)
Jedna z najbardziej przelomowych zmian w Nuxt 4 jest przejscie na plytka reaktywnosc (shallowRef) jako domyslna dla danych zwracanych przez useAsyncData i useFetch. W Nuxt 3 dane byly opakowane w gleboka reaktywnosc (ref), co oznaczalo, ze kazda zmiana zagniezdzonych wlasciwosci obiektu automatycznie wyzwalala aktualizacje komponentow. W Nuxt 4 jedynie zamiana calej wartosci value powoduje re-render.
<script setup lang="ts">
// Data is now a shallowRef by default
const { data: metrics } = await useFetch('/api/dashboard/metrics')
// Direct property mutation won't trigger reactivity
// metrics.value.visits = 100 // Won't trigger re-render
// Replace the entire value to trigger updates
metrics.value = { ...metrics.value, visits: 100 }
// Or opt into deep reactivity for this specific call
const { data: settings } = await useFetch('/api/settings', {
deep: true,
})
</script>Ta zmiana ma bezposredni wplyw na wydajnosc. Gleboka reaktywnosc tworzy proxy dla kazdego zagniezdzonegoobiektu i tablicy, co generuje znaczny narzut pamieci i CPU przy duzych strukturach danych. Plytka reaktywnosc eliminuje ten narzut calkowicie -- system reaktywnosci Vue sledzi jedynie referencje najwyzszego poziomu.
Dla zespolow migrujacych z Nuxt 3 oznacza to koniecznosc przegladu wszystkich miejsc, w ktorych kod bezposrednio mutuje zagniezdzonethe wlasciwosci danych pobranych z useFetch lub useAsyncData. Kazda taka mutacja musi zostac zastapiona pelna zamiana wartosci (spread operator) lub jawnym wlaczeniem glebok reaktywnosci za pomoca opcji deep: true.
Gotowy na rozmowy o Vue.js / Nuxt.js?
Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.
Podzielony kontekst TypeScript (context splitting)
Nuxt 4 dzieli konfiguracje TypeScript na cztery odrebne konteksty zamiast jednego globalnego tsconfig.json. Kazdy kontekst posiada wlasne reguly rozwiazywania typow, co eliminuje problem typow serwerowych widocznych w kodzie klienckim i odwrotnie.
{
"files": [],
"references": [
{ "path": "./.nuxt/tsconfig.app.json" },
{ "path": "./.nuxt/tsconfig.server.json" },
{ "path": "./.nuxt/tsconfig.shared.json" },
{ "path": "./.nuxt/tsconfig.node.json" }
]
}Kontekst app obejmuje kod w katalogu app/, wlacznie z komponentami, stronami i composable'ami. Kontekst server obsluguje pliki w server/, z dostepem do typow Node.js i API serwerowych. Kontekst shared zapewnia typowanie dla katalogu shared/, widoczne zarowno w app, jak i server. Kontekst node pokrywa pliki konfiguracyjne jak nuxt.config.ts.
Ta separacja wymaga zmiany sposobu uruchamiania weryfikacji typow. Flaga -b (project references build mode) jest teraz wymagana dla vue-tsc.
# Before (Nuxt 3)
nuxt prepare && vue-tsc --noEmit
# After (Nuxt 4)
nuxt prepare && vue-tsc -b --noEmitBez flagi -b kompilator TypeScript nie rozpozna referencji miedzy projektami i zglosi bledy dotyczace brakujacych typow. Jest to jedna z najczesciej pomijanych zmian podczas migracji, ktora prowadzi do bledow w pipeline'ach CI/CD.
Znormalizowane nazwy komponentow i Vue Router v5
Nuxt 4 zmienia konwencje nazewnictwa auto-importowanych komponentow. Komponenty zagniezdzone w podkatalogach otrzymuja teraz nazwy oparte na pelnej sciezce katalogu, a nie jedynie na nazwie pliku. Na przyklad komponent components/dashboard/MetricsCard.vue w Nuxt 3 byl dostepny jako DashboardMetricsCard, ale rowniez jako MetricsCard. W Nuxt 4 obowiazuje wylacznie pelna, znormalizowana nazwa.
Ta zmiana ma bezposredni wplyw na konfiguracje <KeepAlive>, ktora wymaga jawnego podania nazw komponentow w tablicy include lub exclude.
<!-- app/pages/dashboard.vue -->
<template>
<NuxtPage :keepalive="{
include: ['DashboardMetricsCard', 'DashboardRecentActivity'],
}" />
</template>Nalezy zweryfikowac, czy nazwy komponentow uzywane w keepalive, <Transition> i dynamicznych komponentach (<component :is="...">) odpowiadaja nowym, znormalizowanym nazwom. W przeciwnym razie KeepAlive przestanie cache'owac komponenty, a przejscia animacyjne nie beda dzialac.
Rownolegle Nuxt 4 integruje Vue Router v5, ktory wprowadza zmiany w API nawigacji i straznkow (guards). Metoda router.resolve() zwraca teraz rozszerzony obiekt z dodatkowymi metadanymi. Straze nawigacyjne otrzymuja ulepszone typowanie parametrow. Zespoly korzystajace z zaawansowanych wzorcow routingu powinny zweryfikowac kompatybilnosc swoich strazy i middleware'ow z nowym API.
Zmiany w zarzadzaniu meta tagami (Unhead v2)
Nuxt 4 przechodzi na Unhead v2, co wprowadza przelmowe zmiany w sposobie zarzadzania meta tagami i elementami <head>. Usuniete zostaly przestarzale wlasciwosci vmid, hid, children i body, ktore w Nuxt 3 byly uzywane do identyfikacji i deduplikacji tagow.
<script setup lang="ts">
const route = useRoute()
const { data: product } = await useFetch(`/api/products/${route.params.id}`)
// Unhead v2: removed vmid, hid, children, body props
useSeoMeta({
title: () => product.value?.name ?? 'Product',
ogTitle: () => product.value?.name ?? 'Product',
description: () => product.value?.description ?? '',
ogImage: () => product.value?.imageUrl ?? '',
})
</script>Dodatkowo niektorych pluginow Unhead, takie jak TemplateParamsPlugin i AliasSortingPlugin, nie sa juz domyslnie ladowane. Jesli projekt korzysta z parametrow szablonowych w meta tagach (np. %s | Nazwa Strony), nalezy je jawnie zarejestrwac jako plugin Nuxt.
import { TemplateParamsPlugin, AliasSortingPlugin } from '@unhead/vue/plugins'
export default defineNuxtPlugin({
setup() {
const unhead = injectHead()
unhead.use(TemplateParamsPlugin)
unhead.use(AliasSortingPlugin)
},
})Brak rejestracji tych pluginow objawia sie subtelnym bledem: szablony tytulu przestaja byc przetwarzane i uzytkownik widzi surowy tekst z symbolami %s zamiast przetworzonego tytulu. Problem ten jest szczegolnie trudny do wykrycia podczas developmentu, poniewaz moze nie wplywac na dzialanie samej aplikacji, a jedynie na metryki SEO.
Lista kontrolna migracji i typowe pulapki
Ponizej znajduje sie kompletna lista kontrolna dla zespolow migrujacych z Nuxt 3 do Nuxt 4. Kazdy punkt powinien zostac zweryfikowany i odznaczony przed wdrozeniem na srodowisko produkcyjne.
- Aktualizacja Nuxt -- uruchomienie
npx nuxt upgrade --dedupei weryfikacja, ze wszystkie zaleznosci sa kompatybilne z Nuxt 4 - Restrukturyzacja katalogow -- uruchomienie codemoodu lub reczne przeniesienie plikow do
app/,shared/iserver/ - Weryfikacja importow -- sprawdzenie, czy wszystkie sciezki importow zostaly zaktualizowane po przeniesieniu plikow
- Aktualizacja composable'ow data fetching -- przeglad wszystkich uzyc
useAsyncDataiuseFetchpod katem nowego APIgetCachedDatai singleton pattern - Dostosowanie do shallow reactivity -- identyfikacja i naprawa wszystkich miejsc z bezposrednia mutacja zagniezdzonych wlasciwosci danych
- Konfiguracja TypeScript -- aktualizacja
tsconfig.jsondo formatu z referencjami projektow i zmiana komendyvue-tscna tryb-b - Nazwy komponentow -- weryfikacja nazw w
keepalive,<Transition>i dynamicznych komponentach pod katem nowych znormalizowanych nazw - Meta tagi (Unhead v2) -- usuniecie przestarzalych wlasciwosci (
vmid,hid,children,body) i rejestracja wymaganych pluginow - Testy E2E -- uruchomienie pelnego zestawu testow end-to-end z uwzglednieniem zmian w nawigacji Vue Router v5
- Pipeline CI/CD -- aktualizacja komend budowania i weryfikacji typow w konfiguracji pipeline'u
Najczestsze pulapki podczas migracji obejmuja:
- Zapomniane mutacje shallow ref -- kod, ktory bezposrednio modyfikuje zagniezdzonethe wlasciwosci
data.value.property = x, przestaje wyzwalac re-rendery. Jest to najczesciej zglaszany problem po migracji - Brakujaca flaga
-bwvue-tsc-- powoduje falszywe bledy typow w CI, ktore nie wystepuja lokalnie - Nieznormalizowane nazwy komponentow w KeepAlive -- KeepAlive po cichu ignoruje nierozpoznane nazwy, co prowadzi do utraty cache'owania bez widocznych bledow
- Brakujace pluginy Unhead -- szablony tytulow przestaja dzialac, co objawia sie dopiero po analizie wynikow w Google Search Console
Aby poglebic wiedze na temat ekosystemu Vue i Nuxt, warto zapoznac sie z pytaniami rekrutacyjnymi Vue/Nuxt oraz przewodnikiem po SSR i generowaniu statycznym.
Podsumowanie
Nuxt 4 stanowi znaczacy krok naprzod w ewolucji frameworka, wprowadzajac zmiany, ktore wplywaja na kazdy aspekt procesu wytwarzania oprogramowania. Kluczowe wnioski z migracji:
- Nowa struktura katalogu
app/separuje kod aplikacji od konfiguracji i zasobow serwerowych, a katalogshared/eliminuje problem duplikowania typow miedzy klientem a serwerem - Singleton data fetching z wzorcem
getCachedDatai obiektem kontekstuctxumozliwia precyzyjna kontrole nad strategia cache'owania i eliminuje zduplikowane zapytania sieciowe - Domyslna shallow reactivity znaczaco poprawia wydajnosc przy duzych strukturach danych, ale wymaga swiadomego dostosowania kodu mutujacego zagniezdzonethe wlasciwosci
- Podzielony kontekst TypeScript zapewnia scisla izolacje typow miedzy kodem klienckim, serwerowym i wspoldzielonym, co eliminuje cala klase bledow typowania
- Znormalizowane nazwy komponentow i integracja Vue Router v5 wymagaja przegladu konfiguracji KeepAlive, przejsc animacyjnych i strazy nawigacyjnych
- Unhead v2 wymusza jawna rejestracje pluginow szablonowych i usunie przestarzale wlasciwosci meta tagow
- Oficjalny codemod automatyzuje restrukturyzacje katalogow, ale pozostale zmiany -- composable'e, TypeScript, meta tagi -- wymagaja recznej weryfikacji i dostosowania
Zacznij ćwiczyć!
Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.
Tagi
Udostępnij
Powiązane artykuły

Vue 3 Pinia vs Vuex: Nowoczesne zarządzanie stanem i pytania rekrutacyjne 2026
Porównanie Pinia i Vuex: architektura, TypeScript, Composition API, migracja, hydratacja SSR oraz najczęstsze pytania rekrutacyjne o zarządzanie stanem Vue na rok 2026.

Nuxt 3: SSR i generowanie statyczne, kompletny przewodnik
Opanowanie SSR i generowania statycznego w Nuxt 3. Od useFetch po route rules: jak optymalizować wydajność aplikacji Vue.js.

Kluczowe pytania rekrutacyjne Vue.js: 25 pytań na zdobycie pracy
Przygotowanie do rozmów Vue.js dzięki 25 kluczowym pytaniom. Od reaktywności po composables, opanuj najważniejsze pojęcia przed kolejną rozmową.