Episode ini membedah arsitektur Nuxt di balik layar: rendering modes SSR, SSG, ISR, dan SPA, peran Nitro sebagai server engine, mekanisme auto-import untuk komponen dan composables, struktur direktori project, serta batas antara kode server dan kode client.

Sekarang kita masuk ke bagian teknis yang paling penting: bagaimana Nuxt bekerja di balik layar. Kalian tidak wajib menghafal semua detail internal, tapi memahami arsitektur utama akan menyelamatkan kalian dari banyak kebingungan — misalnya kenapa sebuah composable berjalan di server, atau kenapa sebuah halaman dirender dua kali.
Episode 2 membahas empat pilar arsitektur Nuxt: rendering modes, server engine Nitro, auto-import, dan struktur project. Kita juga akan melihat bagaimana Nuxt menentukan batas antara kode yang berjalan di server dan kode yang berjalan di browser. Ini adalah lensa yang akan kalian pakai untuk membaca semua episode selanjutnya.
Nuxt bisa merender aplikasi yang sama dengan strategi berbeda, bahkan per halaman. Keempat mode utamanya:
Pengaturan mode memakai routeRules di nuxt.config.ts:
export default defineNuxtConfig({
routeRules: {
"/": { prerender: true },
"/produk/**": { swr: 300 },
"/dashboard/**": { ssr: false }
}
})prerender: true menghasilkan HTML statis saat build, swr membuat halaman dirender ulang setelah jeda detik tertentu, dan ssr: false menjadikan halaman SPA murni.
Nitro adalah server engine Nuxt. Dia merender halaman di server, menyajikan API dari folder server, dan menghasilkan deployment artifact untuk banyak target sekaligus. Keunggulannya: kalian menulis kode server sekali, lalu bisa men-deploy ke Node, Vercel, Netlify, Cloudflare, bahkan serverless functions, tanpa mengubah kode.
export default defineEventHandler(async (event) => {
const body = await readBody(event)
return { status: "ok", data: body }
})Nitro menyediakan utilitas seperti readBody(event) untuk membaca payload request, getQuery(event) untuk query string, dan setCookie untuk mengelola cookie.
Nitro juga punya storage terdistribusi yang bisa diakses dari kode server, berguna untuk cache dan shared state:
const nilai = await useStorage("data").getItem("kunci")
await useStorage("data").setItem("kunci", "nilai")useStorage("data").getItem("kunci") membaca dari storage Nitro yang abstraksinya sama untuk filesystem, Redis, atau Cloudflare KV.
Nuxt secara otomatis mengimpor komponen dari components, composables dari composables, dan utility dari utils. Kalian langsung memakainya di template tanpa baris import:
<template>
<div>
<SiteHeader />
<KartuProduk v-for="item in daftar" :key="item.id" :item="item" />
</div>
</template>
<script setup lang="ts">
const daftar = await useFetch("/api/produk")
</script><SiteHeader /> dan <KartuProduk /> dipakai tanpa import karena Nuxt memindai folder components secara otomatis. useFetch juga auto-import dari Nuxt.
Module adalah cara memperluas Nuxt secara terstruktur. Contoh terkenal: @nuxt/image, @nuxt/content, @pinia/nuxt, dan @nuxtjs/i18n. Modules didaftarkan di nuxt.config.ts dan biasanya mengatur dirinya sendiri saat project dijalankan.
Project Nuxt 4 modern punya struktur berikut:
app/
app.vue
pages/
components/
composables/
layouts/
middleware/
plugins/
server/
api/
nuxt.config.ts
package.jsonapp/ menampung semua kode client-facing, server/ menampung API dan middleware server. Folder public/ untuk aset statis seperti gambar dan favicon.
Setiap file .vue di pages menjadi satu route. Nested routes dibuat dengan folder bernama sama dengan halaman induk. app/pages/produk/index.vue menjadi /produk, dan app/pages/produk/[id].vue menjadi /produk/1.
nuxt.config.ts adalah satu-satunya sumber kebenaran untuk konfigurasi build, modules, dan runtime config. Nilai runtime config bisa diakses dari kode server maupun client sesuai tingkat visibilitasnya — detailnya di episode 8.
Saat pengguna membuka halaman, alurnya kira-kira begini: Nitro menerima request, menjalankan server middleware, merender komponen di server, mengirim HTML plus payload, lalu Vue mengambil alih di browser dan menghidupkan interaktivitas melalui proses yang disebut hydration.
Ini konsep yang paling sering salah dipahami. Kode dalam <script setup> sebuah halaman bisa berjalan dua kali: sekali di server saat render, sekali di client saat hydration. Composables tertentu hanya berjalan di salah satu sisi:
if (import.meta.server) {
console.log("berjalan di server")
}
if (import.meta.client) {
console.log("berjalan di browser")
}Gunakan import.meta.server dan import.meta.client untuk menulis kode spesifik sisi. Episode 6 akan membahas bagaimana pola ini berhubungan dengan pengambilan data.
Episode 2 membuka selubung arsitektur Nuxt: empat rendering modes yang bisa diatur per halaman lewat route rules, Nitro sebagai server engine yang universal, auto-import yang menghilangkan boilerplate import, struktur direktori yang terstandar, serta batas server-client yang jelas.
Inti yang harus dibawa pulang:
routeRules.app/ dan server/ memisahkan kode client-facing dari kode server.pages.<script setup> bisa berjalan di server dan client; kenali batasannya dengan import.meta.server dan import.meta.client.Di episode 3 selanjutnya kita akan membuat project Nuxt pertama secara nyata — memakai npx nuxi init, menjelajahi struktur folder, menjalankan dev server dengan hot reload, dan mengonfigurasi TypeScript, ESLint, serta Prettier. Saatnya tangan kalian mulai mengetik kode.