Câu hỏi phỏng vấn Nuxt 4
A. Tổng quan & Nuxt 4
1. Nuxt là gì?
Meta-framework xây trên Vue 3, kèm sẵn file-based routing, SSR/SSG/Hybrid rendering, auto-import, server engine Nitro, module ecosystem. Tương đương Next.js cho React.
2. Nuxt 4 có gì khác Nuxt 3?
- Cấu trúc
app/mới — code app tách khỏi config. - TypeScript chia 3 project (app/server/shared).
- Data fetching auto share theo key, auto cleanup, clear-on-refetch.
- Drop Nuxt 2 compat.
- Migration codemod tự động.
3. Nuxt 4 release khi nào? Nuxt 3 còn support?
Nuxt 4.0 release 07/2025. Nuxt 3 support đến 01/2026, kèm backport feature.
4. Vì sao chia 3 TS project?
tsconfig.app.json (client + universal), tsconfig.server.json (Node + Nitro), tsconfig.shared.json (strict both). → Type chính xác hơn, server-only util không leak sang client lúc compile.
5. Có nên migrate từ Nuxt 3?
npx nuxt upgrade --dedupe + npx codemod@latest nuxt/4/migration-recipe thường xong vài phút. Migrate khi có thời gian — không gấp vì Nuxt 3 còn support.
6. Compatibility date là gì?
compatibilityDate: '2025-07-01' trong nuxt.config — pin behavior tại 1 thời điểm để upgrade Nuxt không bất ngờ vỡ.
B. Routing
7. File-based routing trong Nuxt — quy ước?
app/pages/index.vue → /. app/pages/users/[id].vue → /users/:id. [...slug].vue catch-all. [[tab]].vue optional param.
8. Nested route?
app/pages/parent.vue + app/pages/parent/child.vue. Parent có <NuxtPage /> để render child.
9. <NuxtLink> khác <a> ra sao?
<NuxtLink> client-side navigation, auto prefetch khi visible viewport. <a> full reload page. External link dùng <NuxtLink external>.
10. useRoute vs useRouter?
useRoute(): route hiện tại (path, params, query) — reactive.useRouter(): programmatic navigation (push, replace, back).
11. navigateTo vs router.push?
navigateTo("/x"): cả server (SSR redirect) và client. Khuyến nghị dùng cái này.router.push("/x"): chỉ client.
12. Middleware Nuxt khác Vue Router beforeEach?
Middleware Nuxt chạy cả server SSR lẫn client. *.global.ts → mọi route. Còn lại register qua definePageMeta({ middleware: "..." }).
13. definePageMeta dùng làm gì?
Config per-page: layout, middleware, validate, transition, scroll behavior.
14. <NuxtPage> và <NuxtLayout> khác <RouterView>?
<NuxtPage> = <RouterView> + thêm transition + keep-alive. <NuxtLayout> wrap chọn layout.
C. Rendering modes
15. SSR vs SSG vs SPA vs ISR?
- SSR: server render mỗi request.
- SSG: build time → static HTML.
- SPA: client only, không server render.
- ISR: SSG + revalidate sau N giây.
16. Hybrid rendering trong Nuxt 4?
Mỗi route 1 mode khác nhau qua routeRules:
routeRules: {
"/": { prerender: true },
"/blog/**": { isr: 600 },
"/admin/**": { ssr: false },
}
17. ISR vs SWR?
- ISR: cache cho đến hết TTL, request đầu sau TTL block để regenerate.
- SWR: trả ngay cached (stale), regenerate background.
18. Khi nào dùng SSR, khi nào SPA?
- SSR: SEO quan trọng (marketing, blog, product page), first paint nhanh.
- SPA: dashboard auth-gated, không cần SEO, UX kiểu app.
19. routeRules đặt ở đâu?
nuxt.config.ts. Apply lúc build + runtime — không cần redeploy mọi route.
20. prerender: true khác ssr: false?
prerender: true(SSG): build time → HTML. Không cần Node server.ssr: false(SPA): client render, vẫn cần server serve index.html.
D. Data fetching
21. useFetch vs $fetch khác gì?
useFetch: SSR-aware, reactive (data, pending, error), cache key, chỉ chạy 1 lần SSR rồi hydrate.$fetch: Promise raw, không reactive, không SSR-aware. Dùng cho event handler / form submit.
22. useFetch vs useAsyncData?
useFetch là wrapper cao cấp của useAsyncData + $fetch. useAsyncData linh hoạt hơn — function bất kỳ trả Promise, combine nhiều API call.
23. Vì sao useFetch SSR-aware?
Chạy 1 lần ở server → kết quả serialize vào HTML payload → client hydrate không gọi lại API. Vừa SEO vừa nhanh first paint.
24. useFetch Nuxt 4 khác Nuxt 3?
- Auto share data cùng key.
- Auto cleanup khi unmount.
- Refetch → clear data về null (Nuxt 3 giữ stale data).
- Reactive key tự refetch.
- Abort control (4.2+).
25. lazy: true trong useFetch để làm gì?
Không block navigation tới khi fetch xong — page render ngay, pending = true, data tới sau.
26. pick và transform trong useFetch?
pick: chỉ giữ fields trong response → giảm payload.transform: biến đổi response trước khi cache.
27. watch option để làm gì?
useFetch("/api/users", { query: { city: filter }, watch: [filter] });
Auto refetch khi reactive value đổi.
28. Làm sao gọi API trên button click?
Dùng $fetch:
async function save() { await $fetch("/api/save", { method: "POST", body: data }); }
Không dùng useFetch trong handler — nó cho data declarative khi load page.
E. State management
29. useState là gì?
Cross-component state SSR-safe. Khác ref module-level: scope theo request ở SSR.
export const useAuth = () => useState("auth", () => ({ user: null }));
30. Khi nào dùng useState vs Pinia?
useState: state đơn giản, scope nhỏ.- Pinia: store phức tạp, có action async, devtools, modular.
31. SSR hydration mismatch — tránh ra sao?
- Dùng
useStatethayrefmodule-level cho shared state. - Tránh
Math.random(),Date.now()ở component gây khác giữa server và client. - Wrap client-only bằng
<ClientOnly>.
32. <ClientOnly> để làm gì?
Skip render component ở SSR — chỉ hydrate ở client. Dùng cho component dùng window, localStorage, lib client-only.
F. Server / Nitro
33. Nitro là gì?
Server engine của Nuxt — đảm nhiệm SSR + API route + middleware. Deploy đa nền tảng (Node, Vercel, Cloudflare, Deno, Bun, Lambda).
34. Server route convention?
server/api/<path>.<method>.ts → endpoint. Ví dụ server/api/users/[id].get.ts → GET /api/users/:id.
35. Đọc body request?
const body = await readBody(event);
36. Throw error 404?
throw createError({ statusCode: 404, statusMessage: "Not Found" });
37. Set cookie?
setCookie(event, "session", "abc", { httpOnly: true, secure: true, sameSite: "lax" });
38. Server middleware chạy khi nào?
server/middleware/*.ts → mọi request. Dùng cho auth, logging.
39. Nitro storage layer là gì?
Abstract KV store qua nhiều backend (memory, filesystem, Redis, Cloudflare KV). useStorage("cache"). Tiện cho cache.
G. Runtime config
40. runtimeConfig vs appConfig?
runtimeConfig: env-var, server secret, có thể override runtime. Key trongpublicmới expose client.appConfig: reactive, exposed client, KHÔNG cho secret.
41. Đọc env var?
// .env: NUXT_API_SECRET=xxx, NUXT_PUBLIC_API_BASE=https://api...
const config = useRuntimeConfig();
config.apiSecret; // server only
config.public.apiBase; // both
42. Bí mật env có thể leak client?
Có nếu để trong runtimeConfig.public hoặc appConfig. Chỉ field ngoài public mới server-only.
H. Auto-import
43. Auto-import có overhead bundle không?
Không. Nuxt scan + add import statement lúc build. Output có import explicit, tree-shake bình thường.
44. Cái gì được auto-import?
app/components/**app/composables/**,shared/utils/**- Vue API (
ref,computed,watch,onMounted...) - Nuxt built-in composables (
useFetch,useState,useRoute,navigateTo...)
45. Tắt auto-import từng case?
// nuxt.config.ts
export default defineNuxtConfig({
imports: { autoImport: false }
});
I. Module & plugin
46. Plugin Nuxt là gì? Khác middleware?
- Plugin: chạy 1 lần khi app khởi tạo, cung cấp helper (
provide). - Middleware: chạy mỗi route navigation.
47. .client.ts và .server.ts suffix?
myPlugin.client.ts: chỉ chạy client.myPlugin.server.ts: chỉ chạy server.- Không suffix: cả 2.
48. Module hot phải biết?
@nuxt/ui, @pinia/nuxt, @nuxt/image, @nuxt/content, @vueuse/nuxt, @nuxtjs/i18n, @nuxtjs/tailwindcss.
J. Performance & deploy
49. Bundle analyzer?
npx nuxt analyze
Mở HTML report xem module nào nặng.
50. Lazy load component?
Prefix Lazy:
<LazyMyHeavyComponent v-if="show" />
Component bundled riêng chunk, load on-demand.
51. Image optimization?
@nuxt/image — <NuxtImg> auto format (avif/webp), srcset responsive, lazy:
<NuxtImg src="/photo.jpg" width="800" sizes="sm:100vw md:50vw" />
52. Deploy lên đâu?
- Vercel / Netlify: auto detect Nuxt, deploy zero-config.
- Cloudflare Pages / Workers:
NITRO_PRESET=cloudflare-pages. - Static (CDN bất kỳ):
npx nuxt generate. - Node:
node .output/server/index.mjs. - Docker: build container chạy Node.
53. .output/ chứa gì?
.output/server/— code server (cho SSR)..output/public/— static asset (deploy CDN).
54. Tối ưu cold start serverless?
- Nitro preset tối ưu cho từng platform.
- Tránh import lib nặng trong server route.
- Cloudflare Workers / edge runtime fast cold start.
K. Câu trick & scenario
55. SSR data fetch — body chứa Date object, hydrate sao?
Payload serialize qua JSON → Date thành string. Nuxt 4 dùng devalue để preserve Date, Map, Set, ... — handle tự động.
56. SEO meta dynamic?
Dùng useSeoMeta với reactive value:
useSeoMeta({ title: () => `Post — ${data.value?.title}` });
57. Auth flow điển hình?
- Server middleware verify token cookie.
- Route middleware
authredirect nếu chưa login. useStatecho user info.- Module
@sidebase/nuxt-authcho NextAuth-style.
58. Vì sao tránh ref module-level?
State module shared giữa request ở SSR → request A thấy state request B. Dùng useState để scope per-request.
59. Khi nào dùng <ClientOnly>?
Component dùng window, document, lib browser-only. Hoặc data từ localStorage không có ở SSR.
60. Nuxt 4 type safety server route?
// server/api/user.get.ts
export default defineEventHandler(async (event) => {
return { id: 1, name: "Alice" };
});
// app/page.vue — type tự inferred từ handler
const { data } = await useFetch("/api/user");
// data.value typed { id: number; name: string } | null
Type-safe API end-to-end mà không cần OpenAPI generator.
61. So sánh Nuxt với Next.js?
- Cả 2: SSR/SSG/Hybrid, file routing, server route.
- Nuxt: Vue, Nitro server đa platform.
- Next: React, Vercel-first, RSC (React Server Components).
- Cộng đồng: Next lớn hơn (ecosystem React); Nuxt gọn gàng hơn, ít boilerplate.
62. Nuxt + Tailwind setup?
npx nuxi@latest module add tailwindcss
Auto setup, config trong tailwind.config.js.
63. i18n trong Nuxt?
npm i @nuxtjs/i18n
modules: ['@nuxtjs/i18n'],
i18n: {
locales: ['en', 'vi'],
defaultLocale: 'vi',
}
Component dùng $t('key') hoặc useI18n().
64. Test Nuxt app?
@nuxt/test-utils + Vitest:
import { setup, $fetch } from '@nuxt/test-utils';
describe('app', async () => {
await setup({});
it('renders home', async () => {
expect(await $fetch('/')).toContain('Welcome');
});
});
65. Migration Nuxt 3 → 4 — bước cụ thể?
npx nuxt upgrade --dedupe.npx codemod@latest nuxt/4/migration-recipe.- Test dev server + tests.
- Sửa
useFetchchỗ phụ thuộc stale data behavior cũ.