Nuxt 4

Giới thiệu và Cài đặt Nuxt 4

Nuxt 4.0 (07/2025) — cấu trúc app/, smarter data fetching, TypeScript chia projects. Cài đặt và project mới.

1. Nuxt là gì?

Nuxt = meta-framework xây trên Vue 3 — kèm sẵn:

  • File-based routing.
  • SSR / SSG / SPA / Hybrid rendering.
  • Auto-import composable, component.
  • Server engine (Nitro) — write API route trong cùng project.
  • Module ecosystem cực rộng.

Tương đương Next.js cho React, SvelteKit cho Svelte.

2. Nuxt 4.0 — bản stable (07/2025)

Cấu trúc app/ mới

Tất cả code app (components/, pages/, layouts/, composables/) chuyển vào app/. Config & dependency ở root → tách biệt rõ.

Smarter data fetching

useFetch/useAsyncData — auto cache theo key, dedupe request, cleanup khi unmount, reactive key tự refetch.

TS chia 3 project

Tách project TS riêng cho app/, server/, shared/ → type inference chính xác, server util không leak sang client.

Performance (4.2)

Abort control cho data fetching, async handler extraction giảm bundle đến 39%, experimental TS plugin support.

Drop legacy

Bỏ Nuxt 2 compat từ @nuxt/kit, một số legacy util gone. Migration codemod chạy được tự động.

Migration painless

npx nuxt upgrade --dedupe + npx codemod@latest nuxt/4/migration-recipe — đa số project xong trong vài phút.

3. Nuxt 3 vs Nuxt 4 — chỗ đổi đáng kể

Nuxt 3 support đến cuối tháng 01/2026 — kèm backport feature từ 4. Bạn không bị ép migrate vội.
Nuxt 3Nuxt 4
Cấu trúcFiles ở rootapp/ directory mặc định
useFetch staleGiữ data cũ khi refetch (stale-while-revalidate)Clear data → null, pending=true
Share data cùng keyKhông tự động✅ Tự động share
TS project1 project tổng3 project (app/server/shared)
Data cleanupManual✅ Auto khi component unmount
Module compat Nuxt 2❌ Drop

Breaking change useFetch data behavior

<!-- Nuxt 3 — stale-while-revalidate -->
<script setup>
const { data, pending } = await useFetch("/api/users");
// Khi refetch — data cũ giữ, pending = true
</script>

<!-- Nuxt 4 — clear immediately -->
<script setup>
const { data, pending } = await useFetch("/api/users");
// Khi refetch — data = null, pending = true
// Muốn giữ behavior cũ: `getCachedData`
</script>

4. Yêu cầu hệ thống

  • Node.js 18.x trở lên (khuyến nghị 20 LTS / 22 LTS).
  • npm / pnpm / yarn / bun.
  • Editor có Volar (Vue Language Server) — VS Code mặc định có.

5. Tạo project mới

# Khuyên dùng — nuxi (CLI chính chủ)
npx nuxi@latest init my-app

# Hoặc với pnpm
pnpm dlx nuxi@latest init my-app

# Vào project
cd my-app
pnpm install
pnpm dev

→ Mở http://localhost:3000.

Cấu trúc khởi tạo (Nuxt 4)

my-app/
├── app/                          ← code app
│   ├── app.vue                   ← root component
│   ├── components/
│   ├── composables/
│   ├── layouts/
│   ├── middleware/
│   ├── pages/
│   ├── plugins/
│   └── assets/
├── server/                       ← API routes, server middleware
│   ├── api/
│   ├── middleware/
│   └── plugins/
├── shared/                       ← code share giữa app + server
│   ├── types/
│   └── utils/
├── public/                       ← static files (favicon, images)
├── content/                      ← (nếu dùng @nuxt/content)
├── .nuxt/                        ← generated, ignore
├── nuxt.config.ts                ← config chính
├── package.json
└── tsconfig.json
Câu PV cốt lõi:"Nuxt 4 vs Nuxt 3 — đổi gì lớn?"

"Lớn nhất: cấu trúc app/ mới — code app tách khỏi config. TypeScript chia 3 project riêng (app/server/shared) → type chính xác hơn, server-only util không truy cập được từ client. Data fetching mới: tự share data cùng key, auto cleanup khi unmount, behavior khi refetch đổi từ stale-while-revalidate sang clear immediately."

6. nuxt.config.ts — file quan trọng nhất

// nuxt.config.ts
export default defineNuxtConfig({
  // Compatibility mode
  compatibilityDate: '2025-07-01',
  
  // App config
  app: {
    head: {
      title: 'My App',
      meta: [{ name: 'description', content: 'My great app' }],
    },
    pageTransition: { name: 'page', mode: 'out-in' },
  },
  
  // Module
  modules: [
    '@nuxt/ui',
    '@pinia/nuxt',
    '@vueuse/nuxt',
    '@nuxt/image',
    '@nuxtjs/i18n',
  ],
  
  // Runtime config — runtime accessible
  runtimeConfig: {
    apiSecret: '',              // server-only (env: NUXT_API_SECRET)
    public: {
      apiBase: '/api',          // exposed to client (env: NUXT_PUBLIC_API_BASE)
    },
  },
  
  // CSS global
  css: ['~/assets/css/main.css'],
  
  // TypeScript
  typescript: {
    strict: true,
    typeCheck: true,            // chạy vue-tsc song song
  },
  
  // Nitro server
  nitro: {
    preset: 'node-server',      // hoặc 'vercel', 'cloudflare', 'static'...
  },
  
  // Dev
  devtools: { enabled: true },
});

Environment variable

# .env
NUXT_API_SECRET=my-secret           # → runtimeConfig.apiSecret (server only)
NUXT_PUBLIC_API_BASE=https://api.x  # → runtimeConfig.public.apiBase (cả client + server)

Dùng trong code:

const config = useRuntimeConfig();
config.apiSecret;          // server only — undefined ở client
config.public.apiBase;     // both
Quan trọng — Security: chỉ key trong public mới expose client. Mọi key khác chỉ server, đừng nhầm.

7. TypeScript trong Nuxt 4

3 TS project tự sinh trong .nuxt/tsconfig.*.json:

ProjectScope
tsconfig.app.jsonCode trong app/ — client + universal
tsconfig.server.jsonCode trong server/ — Node.js, có Nitro types
tsconfig.shared.jsonCode trong shared/ — strict cả 2 môi trường
Lợi ích thực tế: Import fs từ component app/ → TS báo lỗi ngay (không có ở client). Trước Nuxt 3 chỉ runtime mới biết.

8. Auto-import — đặc thù Nuxt

Bạn không cần import cho:

  • Composable trong app/composables/.
  • Component trong app/components/.
  • Built-in composable: useFetch, useState, useRoute, useRouter, useRuntimeConfig, useHead, useSeoMeta, defineNuxtPlugin...
  • Vue 3 reactivity: ref, reactive, computed, watch, onMounted...
  • Utils trong app/utils/shared/utils/.
<!-- Không cần import gì hết -->
<script setup lang="ts">
const count = ref(0);                 // auto-imported
const { data } = await useFetch("/api/users");  // auto
</script>
Câu PV:"Auto-import có overhead bundle không?"

"Không. Auto-import được Nuxt scan và add import statement lúc build. Build output có import explicit như bình thường, tree-shake ngon. Chỉ là tiện DX khi viết, không phải global runtime."

9. Composables built-in cần biết

ComposableTác dụng
useFetch(url)Fetch + cache, SSR-aware
useAsyncData(key, fn)Generic async data với key, SSR-aware
$fetch(url)Fetch raw (không reactive) — dùng trong event handler
useState(key, init)Cross-component SSR-safe state
useRoute()Route hiện tại
useRouter()Programmatic navigation
navigateTo(path)Redirect (cả server + client)
useRuntimeConfig()Runtime config
useHead(meta)Modify <head>
useSeoMeta(meta)SEO-typed meta
useCookie(name)Cookie reactive
useNuxtApp()Truy cập Nuxt instance (plugin, $... helper)

10. Khởi động Hello World

<!-- app/app.vue -->
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>Count: {{ count }}</p>
    <button @click="count++">Increment</button>
  </div>
</template>

<script setup lang="ts">
const title = "Nuxt 4 — Hello!";
const count = ref(0);

useHead({
  title: title,
  meta: [{ name: 'description', content: 'My first Nuxt 4 app' }]
});
</script>
// server/api/hello.ts — server route đầu tiên
export default defineEventHandler(() => ({
  message: "Hello from server!",
  time: new Date().toISOString(),
}));

GET /api/hello trả JSON. Cùng project, không server riêng.

Tiếp theo: Routing & Rendering

© 2026 .NET Fresher Guide. All rights reserved.

Về Trang Web

Hướng dẫn toàn diện để chuẩn bị phỏng vấn vị trí .NET Fresher với nội dung từ lý thuyết đến thực hành.