# Nuxt 4 di Tahun 2026: Struktur Direktori Baru dan Panduan Migrasi dari Nuxt 3 > Panduan lengkap Nuxt 4 mencakup struktur direktori app/, singleton data fetching, shallow reactivity, serta langkah migrasi bertahap dari Nuxt 3 untuk developer Vue.js. - Published: 2026-05-01 - Updated: 2026-05-01 - Author: SharpSkill - Tags: nuxt, vue, migration, typescript, tutorial - Reading time: 9 min --- Nuxt 4 hadir sebagai pembaruan major yang membawa perubahan arsitektural mendasar bagi ekosistem Vue.js. Sejak rilis awal pada Juli 2025 hingga versi 4.4 yang tersedia saat ini, framework ini telah menjalani proses pematangan yang signifikan. Struktur direktori didesain ulang dengan pendekatan yang lebih terorganisasi, data fetching layer dirombak menjadi singleton pattern, dan konteks TypeScript dipisahkan secara ketat antara client, server, serta shared code. Berbeda dengan transisi dramatis dari Nuxt 2 ke Nuxt 3 yang memerlukan penulisan ulang substansial, jalur migrasi kali ini dirancang dengan filosofi evolusioner -- perubahan dapat diadopsi secara bertahap tanpa mengganggu stabilitas aplikasi yang sudah berjalan di production. > **Migrasi Otomatis dengan Codemod** > > Tim Nuxt telah menyediakan codemod resmi yang mengotomatisasi sebagian besar proses migrasi. Perintah `npx codemod@latest nuxt/4/migration-recipe` akan menangani restrukturisasi direktori, pembaruan pola data fetching, serta penggantian API yang sudah deprecated. Pendekatan ini meminimalkan kemungkinan human error selama proses migrasi berlangsung. ## Struktur Direktori app/ yang Baru pada Nuxt 4 Perubahan paling fundamental pada Nuxt 4 terletak pada reorganisasi seluruh kode sumber aplikasi ke dalam direktori `app/`. Keputusan desain ini dilatarbelakangi oleh pertimbangan teknis yang konkret: file watcher pada Linux dan Windows mencatat peningkatan performa yang signifikan ketika kode aplikasi diisolasi dalam subdirektori tersendiri, terpisah dari `node_modules/`, `.git/`, dan berkas konfigurasi lainnya. Pemisahan ini mengurangi jumlah file yang perlu dipantau oleh sistem operasi secara drastis. Berikut gambaran struktur direktori standar pada proyek Nuxt 4: ```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 ``` Hadirnya direktori `shared/` merupakan tambahan yang layak mendapat sorotan khusus. Setiap composable, utility function, atau definisi tipe yang ditempatkan di dalam folder ini akan secara otomatis tersedia baik di sisi aplikasi Vue maupun di server Nitro. Mekanisme auto-import ini menghilangkan kebutuhan untuk menuliskan path import secara manual ketika sebuah validation schema atau helper function perlu digunakan di kedua konteks sekaligus. Dari perspektif organisasi tim, pemisahan yang tegas antara `app/` (kode client), `server/` (kode backend), dan `shared/` (kode lintas konteks) memberikan kejelasan yang sangat berharga. Developer baru yang bergabung ke dalam sebuah proyek dapat segera memahami batasan tanggung jawab masing-masing bagian tanpa perlu mempelajari dokumentasi internal yang panjang. Keuntungan ini semakin terasa pada proyek berskala enterprise dengan puluhan kontributor. ## Langkah Demi Langkah Migrasi dari Nuxt 3 ke Nuxt 4 Proses migrasi dimulai dengan memperbarui package Nuxt ke versi terbaru. Framework ini dirancang untuk mendeteksi struktur flat (gaya Nuxt 3) secara otomatis dan tetap berjalan normal, sehingga tidak ada tekanan untuk memindahkan seluruh file sekaligus. ```bash npx nuxt upgrade --dedupe ``` Setelah dependensi diperbarui dan aplikasi berhasil di-build, tahap berikutnya adalah menjalankan codemod untuk memindahkan file-file aplikasi ke dalam direktori `app/`: ```bash npx codemod@latest nuxt/4/file-structure ``` Codemod ini secara otomatis memindahkan `assets/`, `components/`, `composables/`, `layouts/`, `middleware/`, `pages/`, `plugins/`, `utils/`, `app.vue`, `error.vue`, dan `app.config.ts` ke lokasi barunya di dalam `app/`. Sementara itu, file yang memang seharusnya berada di root proyek -- seperti `nuxt.config.ts`, `server/`, `public/`, dan `content/` -- akan tetap berada di posisi semula. Bagi tim yang belum siap melakukan restrukturisasi penuh karena alasan teknis tertentu (misalnya pipeline CI/CD yang memerlukan penyesuaian), Nuxt 4 menyediakan konfigurasi compatibility yang mempertahankan perilaku Nuxt 3: ```typescript // nuxt.config.ts export default defineNuxtConfig({ srcDir: '.', dir: { app: 'app' }, }) ``` Konfigurasi di atas menginstruksikan Nuxt 4 untuk me-resolve file dari root proyek, sehingga struktur flat tetap berfungsi. Pendekatan ini memungkinkan migrasi dilakukan secara gradual -- misalnya, satu modul per sprint -- tanpa memaksakan perubahan besar dalam satu waktu. ## Singleton Data Fetching Layer dan Reactive Keys Salah satu perubahan terpenting pada Nuxt 4 adalah perombakan data fetching layer menjadi singleton pattern. Pada Nuxt 3, setiap pemanggilan `useAsyncData` atau `useFetch` dengan key yang sama di komponen berbeda menghasilkan salinan data yang independen. Nuxt 4 mengubah perilaku ini: komponen-komponen yang menggunakan key identik kini berbagi satu reactive reference tunggal. ```typescript // app/composables/useProductData.ts 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] }, }, ) } ``` Perubahan ini membawa tiga konsekuensi penting yang perlu dipahami oleh setiap developer Vue.js: Pertama, **shared refs** memastikan bahwa pemanggilan composable yang sama di komponen berbeda -- misalnya `useProductData('abc')` di header dan di sidebar -- akan mengembalikan referensi `data`, `error`, dan `status` yang identik. Pembaruan di satu titik secara otomatis tercermin di titik lainnya. Kedua, **automatic cleanup** menangani pembersihan memori secara transparan. Ketika komponen terakhir yang mereferensikan sebuah key di-unmount, Nuxt akan membebaskan data terkait. Mekanisme ini mencegah memory leak yang kerap terjadi pada aplikasi single-page berdurasi panjang. Ketiga, **reactive keys** memungkinkan penggunaan computed value atau ref sebagai bagian dari key. Perubahan pada nilai tersebut akan memicu refetching secara otomatis tanpa kode imperatif tambahan. Callback `getCachedData` pada contoh di atas menerima objek context dengan properti `cause`. Nilai `cause` dapat berupa `'initial'`, `'refresh:hook'`, `'refresh:manual'`, atau `'watch'`, memberikan kontrol granular atas kapan data segar harus di-fetch versus kapan data dari cache sudah cukup memadai. > **Perubahan Nilai Default dari null ke undefined** > > Nilai default `data` dan `error` dari `useAsyncData` serta `useFetch` berubah dari `null` menjadi `undefined` pada Nuxt 4. Seluruh pengecekan kondisional yang menggunakan `=== null` perlu diperbarui menjadi `=== undefined`, atau sebaiknya menggunakan loose equality check (`== null`) yang menangkap kedua nilai sekaligus. ## Shallow Reactivity sebagai Default untuk Performa Lebih Baik Nuxt 4 mengubah tipe ref yang digunakan oleh `useAsyncData` dan `useFetch` dari `ref` (deep reactive) menjadi `shallowRef`. Implikasi praktisnya adalah Vue tidak lagi melakukan tracking rekursif terhadap setiap properti nested dalam objek data. Untuk response API yang mengandung objek bersarang dalam atau array berukuran besar, perubahan ini menghasilkan peningkatan performa yang terukur karena overhead reactivity system berkurang secara signifikan. ```typescript // app/pages/dashboard.vue ``` Pada sebagian besar skenario -- halaman dashboard, daftar produk, detail artikel, atau timeline aktivitas -- data ditampilkan tanpa mutasi langsung pada properti nested. Untuk kasus-kasus tersebut, shallow reactivity bekerja dengan sempurna tanpa memerlukan perubahan kode sedikitpun. Opsi `deep: true` tetap tersedia untuk situasi spesifik seperti form editing atau komponen interaktif yang memodifikasi properti bagian dalam secara langsung. Filosofi di balik perubahan ini sejalan dengan prinsip yang semakin diadopsi oleh framework modern: memberikan default yang optimal untuk mayoritas kasus penggunaan, sambil tetap menyediakan escape hatch bagi skenario yang membutuhkan perilaku berbeda. ## Pemisahan Konteks TypeScript dan Peningkatan Type Safety Nuxt 4 menghasilkan empat konfigurasi TypeScript terpisah, masing-masing untuk konteks yang berbeda: - `.nuxt/tsconfig.app.json` -- konteks aplikasi Vue (komponen, pages, composables) - `.nuxt/tsconfig.server.json` -- konteks server Nitro (API routes, server middleware) - `.nuxt/tsconfig.shared.json` -- konteks shared (utility lintas konteks) - `.nuxt/tsconfig.node.json` -- konteks build-time (konfigurasi, scripts) Pemisahan ini menghasilkan pengalaman development yang jauh lebih baik. IDE tidak lagi menyarankan API server (misalnya `defineEventHandler`) ketika developer sedang menulis kode komponen Vue, dan sebaliknya. Autocompletion menjadi lebih akurat, dan kesalahan import lintas konteks yang sebelumnya lolos dari pengecekan statis kini terdeteksi sejak dini. File `tsconfig.json` di root proyek bertindak sebagai project reference yang menghubungkan keempat konfigurasi tersebut: ```json { "files": [], "references": [ { "path": "./.nuxt/tsconfig.app.json" }, { "path": "./.nuxt/tsconfig.server.json" }, { "path": "./.nuxt/tsconfig.shared.json" }, { "path": "./.nuxt/tsconfig.node.json" } ] } ``` Perubahan ini berdampak pada cara type checking dijalankan di pipeline CI/CD. Perintah `vue-tsc` kini memerlukan flag `-b` (build mode) agar project references diproses dengan benar: ```bash # Before (Nuxt 3) nuxt prepare && vue-tsc --noEmit # After (Nuxt 4) nuxt prepare && vue-tsc -b --noEmit ``` Perlu dicatat pula bahwa `compilerOptions.noUncheckedIndexedAccess` kini diaktifkan secara default. Akses elemen array atau properti objek melalui index sekarang mengembalikan `T | undefined`, bukan `T`. Perubahan ini membantu menangkap potensi error runtime -- seperti mengakses `array[5]` pada array yang hanya memiliki tiga elemen -- pada saat compile time. ## Normalisasi Nama Komponen dan Integrasi Vue Router v5 Nuxt 4.3 melakukan upgrade ke Vue Router v5, menghapus dependensi pada `unplugin-vue-router` yang sebelumnya digunakan untuk file-based routing. Bagi sebagian besar aplikasi, perpindahan ini bersifat transparan dan tidak memerlukan modifikasi kode. Aspek yang lebih berdampak adalah normalisasi penamaan komponen. Nuxt 4 menerapkan konvensi penamaan yang konsisten berdasarkan lokasi file di dalam direktori `components/`. Sebuah file yang terletak di `components/dashboard/MetricsCard.vue` akan secara otomatis mendapatkan nama `DashboardMetricsCard` di seluruh konteks -- termasuk ``, Vue DevTools, stack trace error, dan test utilities. ```vue ``` Proyek yang menggunakan `` dengan filter `include` atau `exclude` berdasarkan nama komponen perlu memverifikasi dan memperbarui string nama yang digunakan. Perilaku lama, di mana nama komponen bisa bervariasi tergantung konteks pemanggilan, tidak lagi berlaku. Standardisasi ini menyederhanakan proses debugging dan memudahkan komunikasi antar anggota tim ketika membahas komponen tertentu. ## Menangani Breaking Changes pada Head Management Nuxt 4 mengintegrasikan Unhead v2, yang membawa breaking changes pada API `useHead` dan `useSeoMeta`. Properti yang sudah di-deprecate sejak lama -- seperti `vmid`, `hid`, `children`, dan `body` -- telah dihapus sepenuhnya. Penggunaan reactive getter (fungsi tanpa argumen) kini menjadi pola yang direkomendasikan untuk meta tag yang bergantung pada data dinamis: ```typescript // app/pages/product/[id].vue ``` Fitur template parameters (`%s` di dalam title template) dan alias sorting yang sebelumnya tersedia secara bawaan kini perlu diinstal sebagai plugin eksplisit apabila masih dibutuhkan: ```typescript // app/plugins/unhead.ts import { TemplateParamsPlugin, AliasSortingPlugin } from '@unhead/vue/plugins' export default defineNuxtPlugin({ setup() { const unhead = injectHead() unhead.use(TemplateParamsPlugin) unhead.use(AliasSortingPlugin) }, }) ``` > **Batas Waktu Dukungan Nuxt 3** > > Nuxt 3 akan terus menerima security patches dan perbaikan bug kritis hingga 31 Juli 2026. Setelah tanggal tersebut, Nuxt 3 secara resmi memasuki status end-of-life dan tidak lagi didukung. Merencanakan serta mengeksekusi migrasi sebelum tenggat waktu tersebut sangat penting untuk memastikan aplikasi production tidak berjalan pada versi framework yang sudah tidak dipelihara. ## Checklist Migrasi dan Kesalahan Umum yang Perlu Diwaspadai Meskipun codemod otomatis menangani mayoritas perubahan struktural, terdapat sejumlah item yang memerlukan perhatian manual dari developer: - **Penghapusan `window.__NUXT__`**: Objek global ini dihapus setelah proses hydration pada Nuxt 4. Seluruh akses langsung perlu diganti dengan `useNuxtApp().payload` yang merupakan API resmi untuk mengakses payload data. - **Hook `pages:extend` digantikan oleh `pages:resolved`**: Hook baru ini dieksekusi setelah proses scanning page meta selesai, memberikan akses ke informasi halaman yang lebih lengkap dan akurat. - **Perubahan parameter `dedupe`**: Nilai boolean diganti dengan string deskriptif. `refresh({ dedupe: true })` menjadi `refresh({ dedupe: 'cancel' })`, sementara `false` menjadi `'defer'`. Perubahan ini memberikan kejelasan semantik tentang perilaku yang diinginkan. - **Inline styles terbatas pada komponen Vue**: CSS global kini dimuat sebagai file terpisah secara default. Tambahkan `features: { inlineStyles: true }` pada konfigurasi untuk mengembalikan perilaku Nuxt 3 jika diperlukan. - **`clearNuxtState` melakukan reset ke initial value**: Perilaku lama yang mereset ke `undefined` dapat dipertahankan dengan `clearNuxtState('key', { reset: false })`. Berikut urutan migrasi yang direkomendasikan untuk aplikasi production: 1. Jalankan `npx nuxt upgrade --dedupe` dan pastikan aplikasi berhasil di-build tanpa error 2. Eksekusi codemod lengkap: `npx codemod@latest nuxt/4/migration-recipe` 3. Restrukturisasi file ke dalam `app/` (ditangani oleh file-structure codemod) 4. Perbarui seluruh pengecekan `=== null` menjadi `=== undefined` pada logika data fetching 5. Verifikasi konfigurasi `` dengan nama komponen yang sudah dinormalisasi 6. Sesuaikan pipeline CI untuk menggunakan `vue-tsc -b --noEmit` 7. Jalankan full test suite dan tangani error TypeScript baru yang muncul dari `noUncheckedIndexedAccess` Untuk memperdalam pemahaman tentang konsep-konsep Nuxt yang sering diujikan dalam proses rekrutmen, SharpSkill menyediakan materi [pertanyaan wawancara Vue/Nuxt](/technologies/vue-nuxt/interview-questions/nuxt-fundamentals) yang mencakup topik-topik kunci dari Nuxt 3 hingga Nuxt 4. Selain itu, [panduan SSR dan static generation](/blog/vue-nuxt/nuxt-3-ssr-static-generation) memberikan fondasi pemahaman tentang strategi rendering yang tetap relevan pada versi terbaru. ## Kesimpulan Migrasi dari Nuxt 3 ke Nuxt 4 merupakan langkah strategis yang membawa perbaikan arsitektural dan peningkatan developer experience secara menyeluruh. Berikut rangkuman poin-poin kunci yang perlu dikuasai: - Nuxt 4.4 telah menstabilkan struktur direktori `app/`, singleton data fetching layer, dan pemisahan konteks TypeScript sebagai fitur yang siap digunakan di lingkungan production - Perintah `npx codemod@latest nuxt/4/migration-recipe` mengotomatisasi restrukturisasi direktori, penggantian API deprecated, dan pembaruan pola data fetching dalam satu langkah - Shallow reactivity melalui `shallowRef` meningkatkan performa secara default untuk halaman yang dominan menampilkan data, tanpa memerlukan perubahan kode pada sebagian besar kasus - Konfigurasi TypeScript terpisah per konteks (app, server, shared, node) mengeliminasi kebocoran tipe lintas konteks dan menghasilkan autocompletion IDE yang lebih presisi - Dukungan Nuxt 3 berakhir pada 31 Juli 2026 -- migrasi sebelum tanggal tersebut memastikan aplikasi tetap menerima security patches dan perbaikan bug - Vue Router v5 dan Unhead v2 membawa API yang lebih bersih namun menghapus sejumlah properti deprecated yang perlu diaudit secara menyeluruh selama proses migrasi Penguasaan terhadap perubahan-perubahan ini bukan hanya relevan untuk kebutuhan teknis sehari-hari, melainkan juga merupakan materi yang kerap diujikan dalam interview untuk posisi Vue.js developer. Pemahaman mendalam tentang singleton data fetching, TypeScript context splitting, dan strategi migrasi bertahap menunjukkan tingkat kompetensi yang diapresiasi oleh tim rekrutmen di industri. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/id/blog/vue-nuxt/nuxt-4-directory-structure-migration