# Checklist Migration Next.js 15 & React 19
> **Phiên bản:** Next.js 15.x | React 19.x
> **Cập nhật:** 2025
> **Mức độ:** Production-ready migration guide
---
## Mục lục
- [1. Pre-Migration Checks](#1-pre-migration-checks)
- [2. Breaking Changes](#2-breaking-changes)
- [3. App Router Specific Changes](#3-app-router-specific-changes)
- [4. Third-party Libraries](#4-third-party-libraries)
- [5. Testing Checklist](#5-testing-checklist)
---
## 1. Pre-Migration Checks
### 1.1 Môi trường & Node.js
- [ ] **Kiểm tra Node.js version** — Next.js 15 yêu cầu tối thiểu **Node.js 18.17.0**
```bash
node --version
# Yêu cầu: >= 18.17.0
```
- [ ] Upgrade Node.js nếu cần (khuyến nghị dùng **Node.js 20 LTS** hoặc **22 LTS**)
- [ ] Kiểm tra `.nvmrc` hoặc `.node-version` trong project và cập nhật
- [ ] Cập nhật CI/CD pipeline (GitHub Actions, GitLab CI, Vercel...) với Node.js version mới
- [ ] Kiểm tra `engines` field trong `package.json`
```json
{
"engines": {
"node": ">=18.17.0"
}
}
```
### 1.2 Backup & Chuẩn bị
- [ ] Tạo branch mới cho migration (ví dụ: `feat/nextjs-15-migration`)
- [ ] Commit toàn bộ thay đổi hiện tại, đảm bảo working tree sạch
- [ ] Backup `package.json` và `package-lock.json` / `yarn.lock` / `pnpm-lock.yaml`
- [ ] Đảm bảo test suite hiện tại đang **PASS 100%** trước khi migrate
- [ ] Ghi chép lại các custom configurations hiện có (`next.config.js`, middleware...)
### 1.3 Upgrade Dependencies
- [ ] Chạy codemod tự động của Next.js 15
```bash
npx @next/codemod@canary upgrade latest
```
- [ ] Hoặc upgrade thủ công
```bash
# npm
npm install next@latest react@latest react-dom@latest
# yarn
yarn add next@latest react@latest react-dom@latest
# pnpm
pnpm add next@latest react@latest react-dom@latest
```
- [ ] Kiểm tra version sau khi upgrade
```bash
npx next --version
# Expected: Next.js 15.x.x
```
- [ ] Upgrade TypeScript lên **5.x** (nếu dùng TypeScript)
```bash
npm install typescript@latest @types/node@latest @types/react@latest @types/react-dom@latest
```
- [ ] Kiểm tra `eslint-config-next` tương thích
```bash
npm install eslint-config-next@latest
```
### 1.4 Kiểm tra Dependencies Conflicts
- [ ] Chạy audit dependencies
```bash
npm ls react react-dom
# Đảm bảo không có version conflict
```
- [ ] Kiểm tra `peerDependencies` warnings
- [ ] Resolve tất cả `ERESOLVE` errors trước khi tiếp tục
---
## 2. Breaking Changes Cần Xử Lý
### 2.1 Async `params` trong Route Segments
> **⚠️ BREAKING:** `params` prop trong pages, layouts, metadata giờ là **Promise** — phải `await` trước khi dùng.
- [ ] Tìm tất cả files sử dụng `params` trong `app/` directory
```bash
grep -r "params\." app/ --include="*.tsx" --include="*.ts" -l
```
- [ ] Cập nhật **Page components** để `await params`
```tsx
// ❌ TRƯỚC (Next.js 14)
export default function Page({ params }: { params: { slug: string } }) {
return
{params.slug}
;
}
// ✅ SAU (Next.js 15)
export default async function Page({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
return {slug}
;
}
```
- [ ] Cập nhật **Layout components**
```tsx
// ❌ TRƯỚC
export default function Layout({
children,
params,
}: {
children: React.ReactNode;
params: { lang: string };
}) {
return {children};
}
// ✅ SAU
export default async function Layout({
children,
params,
}: {
children: React.ReactNode;
params: Promise<{ lang: string }>;
}) {
const { lang } = await params;
return {children};
}
```
- [ ] Cập nhật `generateMetadata` function
```tsx
// ❌ TRƯỚC
export async function generateMetadata({
params,
}: {
params: { id: string };
}) {
return { title: `Product ${params.id}` };
}
// ✅ SAU
export async function generateMetadata({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
return { title: `Product ${id}` };
}
```
- [ ] Cập nhật `generateStaticParams`
- [ ] Chạy codemod tự động cho `params`
```bash
npx @next/codemod@canary next-async-request-api .
```
### 2.2 Async `searchParams`
> **⚠️ BREAKING:** `searchParams` trong Page components giờ là **Promise**.
- [ ] Tìm tất cả files sử dụng `searchParams`
```bash
grep -r "searchParams" app/ --include="*.tsx" --include="*.ts" -l
```
- [ ] Cập nhật Page components có `searchParams`
```tsx
// ❌ TRƯỚC
export default function SearchPage({
searchParams,
}: {
searchParams: { q: string; page: string };
}) {
return Query: {searchParams.q}
;
}
// ✅ SAU
export default async function SearchPage({
searchParams,
}: {
searchParams: Promise<{ q: string; page: string }>;
}) {
const { q, page } = await searchParams;
return Query: {q}
;
}
```
- [ ] Cập nhật `generateMetadata` sử dụng `searchParams`
- [ ] Kiểm tra Client Components — nếu cần `searchParams` trong Client Component, dùng `useSearchParams()` hook thay thế
```tsx
// ✅ Client Component — dùng hook
"use client";
import { useSearchParams } from "next/navigation";
export default function SearchClient() {
const searchParams = useSearchParams();
const q = searchParams.get("q");
return Query: {q}
;
}
```
### 2.3 Async `cookies()` và `headers()`
> **⚠️ BREAKING:** Các functions `cookies()`, `headers()`, `draftMode()` từ `next/headers` giờ trả về **Promise**.
- [ ] Tìm tất cả usages
```bash
grep -r "cookies()\|headers()\|draftMode()" app/ --include="*.tsx" --include="*.ts" -l
```
- [ ] Cập nhật `cookies()`
```tsx
// ❌ TRƯỚC
import { cookies } from "next/headers";
export default function Page() {
const cookieStore = cookies();
const token = cookieStore.get("token");
return {token?.value}
;
}
// ✅ SAU
import { cookies } from "next/headers";
export default async function Page() {
const cookieStore = await cookies();
const token = cookieStore.get("token");
return {token?.value}
;
}
```
- [ ] Cập nhật `headers()`
```tsx
// ❌ TRƯỚC
import { headers } from "next/headers";
export default function Page() {
const headersList = headers();
const userAgent = headersList.get("user-agent");
return {userAgent}
;
}
// ✅ SAU
import { headers } from "next/headers";
export default async function Page() {
const headersList = await headers();
const userAgent = headersList.get("user-agent");
return {userAgent}
;
}
```
- [ ] Cập nhật `cookies()` trong **Server Actions**
```tsx
// ✅ SAU — trong Server Action
"use server";
import { cookies } from "next/headers";
export async function setTheme(theme: string) {
const cookieStore = await cookies();
cookieStore.set("theme", theme);
}
```
- [ ] Cập nhật `draftMode()`
```tsx
// ✅ SAU
import { draftMode } from "next/headers";
export default async function Page() {
const { isEnabled } = await draftMode();
return Draft: {isEnabled ? "ON" : "OFF"}
;
}
```
- [ ] Chạy codemod cho headers/cookies
```bash
npx @next/codemod@canary next-async-request-api .
```
### 2.4 `forwardRef` Deprecated — React 19
> **⚠️ BREAKING (React 19):** `ref` giờ là prop thông thường. `forwardRef` không còn cần thiết và sẽ bị deprecated.
- [ ] Tìm tất cả `forwardRef` usages
```bash
grep -r "forwardRef" src/ components/ --include="*.tsx" --include="*.ts" -l
```
- [ ] Refactor components dùng `forwardRef`
```tsx
// ❌ TRƯỚC (React 18)
import { forwardRef } from "react";
const Input = forwardRef(
({ placeholder }, ref) => {
return ;
}
);
Input.displayName = "Input";
export default Input;
// ✅ SAU (React 19) — ref là prop bình thường
type InputProps = {
placeholder: string;
ref?: React.Ref;
};
export default function Input({ placeholder, ref }: InputProps) {
return ;
}
```
- [ ] Cập nhật TypeScript types cho `ref` prop
```tsx
// ✅ Pattern chuẩn React 19 với TypeScript
type ButtonProps = React.ComponentProps<"button"> & {
variant?: "primary" | "secondary";
};
export default function Button({ variant = "primary", ref, ...props }: ButtonProps) {
return ;
}
```
- [ ] Chạy codemod tự động
```bash
npx @next/codemod@canary next-comp-link-passthrough-ref .
```
- [ ] Kiểm tra component libraries tự build có dùng `forwardRef` không
- [ ] Lưu ý: `forwardRef` vẫn hoạt động trong React 19 (backward compatible) nhưng sẽ hiện warning
### 2.5 Fetch Caching Behavior Thay Đổi
> **⚠️ BREAKING:** Mặc định fetch requests **không còn được cache** (thay đổi từ `force-cache` sang `no-store`).
- [ ] Review tất cả `fetch()` calls trong Server Components
```bash
grep -r "fetch(" app/ --include="*.tsx" --include="*.ts" -l
```
- [ ] Thêm explicit cache option cho fetch calls cần cache
```tsx
// ❌ TRƯỚC — tự động cache (Next.js 14 default)
const data = await fetch("https://api.example.com/data");
// ✅ SAU — phải explicit nếu muốn cache
// Option 1: Force cache
const data = await fetch("https://api.example.com/data", {
cache: "force-cache",
});
// Option 2: Revalidate theo thời gian
const data = await fetch("https://api.example.com/data", {
next: { revalidate: 3600 }, // 1 giờ
});
// Option 3: No cache (đây là default mới)
const data = await fetch("https://api.example.com/data", {
cache: "no-store",
});
```
- [ ] Xem xét sử dụng `unstable_cache` cho data không từ fetch
```tsx
import { unstable_cache } from "next/cache";
const getCachedData = unstable_cache(
async (id: string) => {
return db.query(id); // Database query
},
["cache-key"],
{ revalidate: 3600 }
);
```
- [ ] Cập nhật `next.config.js` nếu muốn giữ behavior cũ (không khuyến nghị)
```js
// next.config.js — chỉ dùng nếu cần backward compat tạm thời
module.exports = {
experimental: {
staleTimes: {
dynamic: 30,
static: 180,
},
},
};
```
### 2.6 `` Component — Bỏ `` Tag con
> **⚠️ BREAKING:** Không còn render `` tag bên trong `` — đã xử lý từ Next.js 13 nhưng codemod vẫn cần chạy.
- [ ] Kiểm tra và remove các `` tag lồng trong ``
```tsx
// ❌ SAI
About
// ✅ ĐÚNG
About
```
- [ ] Chạy codemod
```bash
npx @next/codemod@canary new-link .
```
### 2.7 `ReactDOM.render` và `ReactDOM.hydrate` Removed
> **⚠️ BREAKING (React 19):** Đã bị xóa hoàn toàn.
- [ ] Tìm kiếm usages
```bash
grep -r "ReactDOM.render\|ReactDOM.hydrate" src/ --include="*.tsx" --include="*.ts"
```
- [ ] Replace bằng `createRoot` và `hydrateRoot`
```tsx
// ❌ TRƯỚC (React 17/18)
import ReactDOM from "react-dom";
ReactDOM.render(, document.getElementById("root"));
// ✅ SAU (React 19)
import { createRoot } from "react-dom/client";
const root = createRoot(document.getElementById("root")!);
root.render();
```
### 2.8 Context API Changes — React 19
> `Context.Provider` được thay bằng `Context` trực tiếp.
- [ ] Tìm `Context.Provider` usages
```bash
grep -r "\.Provider" src/ components/ --include="*.tsx" -l
```
- [ ] Cập nhật Context Provider
```tsx
// ❌ TRƯỚC (React 18)
const ThemeContext = createContext("light");
export function ThemeProvider({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
// ✅ SAU (React 19) — render Context trực tiếp
const ThemeContext = createContext("light");
export function ThemeProvider({ children }: { children: React.ReactNode }) {
return {children};
}
```
- [ ] Lưu ý: `Context.Provider` vẫn hoạt động (backward compatible) nhưng sẽ deprecated
### 2.9 `next/font` API Updates
- [ ] Kiểm tra font imports vẫn hoạt động đúng
- [ ] Đảm bảo không dùng `@next/font` (deprecated) — phải dùng `next/font`
```tsx
// ❌ DEPRECATED
import { Inter } from "@next/font/google";
// ✅ ĐÚNG
import { Inter } from "next/font/google";
```
### 2.10 Turbopack (Stable trong Next.js 15)
- [ ] Thử enable Turbopack cho development
```bash
next dev --turbopack
```
- [ ] Hoặc cập nhật `package.json` scripts
```json
{
"scripts": {
"dev": "next dev --turbopack"
}
}
```
- [ ] Kiểm tra custom webpack config có conflict với Turbopack không
- [ ] Kiểm tra các babel plugins — Turbopack không dùng Babel mặc định
---
## 3. App Router Specific Changes
### 3.1 Server Components & Client Components
- [ ] Review ranh giới Server/Client Components trong app
- [ ] Đảm bảo `"use client"` directive đúng vị trí
- [ ] Kiểm tra không import Server-only modules vào Client Components
```bash
npm install server-only
```
```tsx
// Thêm vào đầu file chỉ chạy trên server
import "server-only";
```
- [ ] Kiểm tra không import Client-only modules vào Server Components
```bash
npm install client-only
```
- [ ] Review việc truyền functions qua Server → Client (phải là Server Actions)
### 3.2 Server Actions
- [ ] Thêm `"use server"` directive cho tất cả Server Actions
- [ ] Kiểm tra Server Actions không expose sensitive data
- [ ] Validate input trong Server Actions với Zod hoặc tương tự
```tsx
"use server";
import { z } from "zod";
import { revalidatePath } from "next/cache";
const schema = z.object({
title: z.string().min(1).max(100),
});
export async function createPost(formData: FormData) {
const validated = schema.safeParse({
title: formData.get("title"),
});
if (!validated.success) {
return { error: validated.error.flatten() };
}
// ... create post logic
revalidatePath("/posts");
}
```
- [ ] Kiểm tra error handling trong Server Actions
- [ ] Test Server Actions với `useActionState` (React 19 — đã replace `useFormState`)
```tsx
// ❌ TRƯỚC (React 18 / next/dist)
import { useFormState } from "react-dom";
// ✅ SAU (React 19)
import { useActionState } from "react";
export function PostForm() {
const [state, action, isPending] = useActionState(createPost, null);
return (
);
}
```
### 3.3 Metadata API
- [ ] Kiểm tra `generateMetadata` async pattern (xem phần 2.1)
- [ ] Kiểm tra `viewport` export — đã tách khỏi `metadata` object
```tsx
// ❌ TRƯỚC — viewport trong metadata
export const metadata = {
themeColor: "#000000",
viewport: "width=device-width, initial-scale=1",
};
// ✅ SAU — viewport export riêng
import type { Viewport } from "next";
export const viewport: Viewport = {
themeColor: "#000000",
width: "device-width",
initialScale: 1,
};
export const metadata = {
title: "My App",
};
```
- [ ] Kiểm tra `metadataBase` được set trong root layout
### 3.4 Route Handlers
- [ ] Kiểm tra Route Handlers (`app/api/**/route.ts`) vẫn hoạt động
- [ ] Cập nhật `params` trong Route Handlers
```tsx
// ❌ TRƯỚC
export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {
return Response.json({ id: params.id });
}
// ✅ SAU
export async function GET(
request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
return Response.json({ id });
}
```
- [ ] Kiểm tra `NextRequest` / `NextResponse` vẫn import đúng
### 3.5 Middleware Updates
- [ ] Kiểm tra `middleware.ts` vẫn hoạt động đúng
- [ ] Kiểm tra `matcher` config trong middleware
```tsx
// middleware.ts
export const config = {
matcher: [
"/((?!_next/static|_next/image|favicon.ico).*)",
],
};
```
- [ ] Test authentication middleware flow
- [ ] Kiểm tra middleware không sử dụng Node.js-specific APIs (chạy trên Edge Runtime)
### 3.6 Error Handling
- [ ] Kiểm tra `error.tsx` trong các route segments
- [ ] Kiểm tra `global-error.tsx` trong root app directory
- [ ] Đảm bảo `error.tsx` là Client Component
```tsx
// app/error.tsx
"use client"; // ← BẮT BUỘC
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
Đã có lỗi xảy ra!
);
}
```
### 3.7 Loading UI & Suspense
- [ ] Review `loading.tsx` files
- [ ] Kiểm tra Suspense boundaries vẫn hoạt động đúng
- [ ] Test streaming SSR behavior
- [ ] Kiểm tra `loading.tsx` không bị conflict với Suspense manual
### 3.8 Image Component
- [ ] Kiểm tra `next/image` usage — API ổn định, không có breaking change lớn
- [ ] Đảm bảo `alt` prop có giá trị meaningful (accessibility)
- [ ] Kiểm tra `remotePatterns` trong `next.config.js` thay vì `domains` (deprecated)
```js
// next.config.js
module.exports = {
images: {
// ❌ DEPRECATED
// domains: ['example.com'],
// ✅ ĐÚNG
remotePatterns: [
{
protocol: "https",
hostname: "example.com",
port: "",
pathname: "/images/**",
},
],
},
};
```
---
## 4. Third-party Libraries — Kiểm Tra Tương Thích
### 4.1 State Management
- [ ] **Redux Toolkit** — Kiểm tra version `>= 2.x` tương thích React 19
```bash
npm ls @reduxjs/toolkit react-redux
# react-redux >= 9.x cho React 19
```
- [ ] **Zustand** — Kiểm tra version `>= 4.x`
```bash
npm ls zustand
# zustand >= 4.4.x cho React 19
```
- [ ] **Jotai** — Kiểm tra version `>= 2.x`
- [ ] **Recoil** — ⚠️ Chú ý: Recoil không được maintain tích cực, cân nhắc migrate sang Jotai
### 4.2 Data Fetching & Server State
- [ ] **TanStack Query (React Query)** — Yêu cầu `>= 5.x` cho React 19
```bash
npm ls @tanstack/react-query
# Yêu cầu: >= 5.0.0
```
- [ ] **SWR** — Kiểm tra version `>= 2.x`
```bash
npm ls swr
# swr >= 2.2.x khuyến nghị
```
- [ ] **Apollo Client** — Kiểm tra `>= 3.9.x` cho React 19 support
- [ ] **tRPC** — Kiểm tra version `>= 11.x`
### 4.3 UI Component Libraries
- [ ] **shadcn/ui** — Cập nhật components, tương thích tốt với React 19
```bash
npx shadcn@latest diff # Xem thay đổi
```
- [ ] **Radix UI** — Kiểm tra `>= 1.x` primitives
```bash
npm ls @radix-ui/react-dialog # Kiểm tra từng package
```
- [ ] **Headless UI** — Kiểm tra version `>= 2.x` cho React 19
- [ ] **Chakra UI** — Kiểm tra `>= 3.x` (có breaking changes lớn)
- [ ] **Material UI (MUI)** — Kiểm tra `>= 6.x` cho React 19
```bash
npm ls @mui/material
# MUI >= 6.0.0 hỗ trợ React 19
```
- [ ] **Ant Design** — Kiểm tra `>= 5.x`
- [ ] **Mantine** — Kiểm tra `>= 7.x`
### 4.4 Form Libraries
- [ ] **React Hook Form** — Kiểm tra version `>= 7.x`
```bash
npm ls react-hook-form
# >= 7.50.x cho React 19
```
- [ ] **Formik** — ⚠️ Chú ý: Formik không được maintain tích cực
- [ ] **Zod** (validation) — Kiểm tra `>= 3.x`, tương thích tốt
### 4.5 Animation
- [ ] **Framer Motion** — Kiểm tra `>= 11.x` cho React 19
```bash
npm ls framer-motion
# >= 11.0.0 khuyến nghị
```
- [ ] **React Spring** — Kiểm tra `>= 9.x`
- [ ] **GSAP** — Kiểm tra plugin compatibility
### 4.6 Styling
- [ ] **Tailwind CSS** — Kiểm tra `>= 3.4.x`, Tailwind v4 đang trong beta
```bash
npm ls tailwindcss
```
- [ ] **styled-components** — Kiểm tra `>= 6.x` cho React 19 Server Components
> ⚠️ Lưu ý: styled-components không hoạt động với Server Components, chỉ dùng với `"use client"`
- [ ] **Emotion** — Tương tự styled-components, chỉ Client Components
- [ ] **CSS Modules** — Hoạt động tốt, không có breaking change
### 4.7 Authentication
- [ ] **NextAuth.js (Auth.js)** — Migrate lên `>= 5.x` (Auth.js)
```bash
npm ls next-auth
# next-auth >= 5.0.0 (Auth.js) cho Next.js 15
```
> ⚠️ NextAuth v5 có breaking changes lớn so với v4
- [ ] **Clerk** — Kiểm tra `@clerk/nextjs >= 5.x`
- [ ] **Supabase Auth** — Kiểm tra `@supabase/ssr` package mới thay vì `@supabase/auth-helpers-nextjs`
### 4.8 Testing Libraries
- [ ] **Jest** — Kiểm tra config tương thích với Next.js 15
```bash
npm ls jest @testing-library/react @testing-library/jest-dom
# @testing-library/react >= 15.x cho React 19
```
- [ ] **Playwright** — Kiểm tra `>= 1.40.x`
- [ ] **Cypress** — Kiểm tra `>= 13.x`
- [ ] **Vitest** — Kiểm tra `>= 1.x`, tương thích tốt
- [ ] Cập nhật Jest config cho Next.js 15
```js
// jest.config.js
const nextJest = require("next/jest");
const createJestConfig = nextJest({ dir: "./" });
module.exports = createJestConfig({
testEnvironment: "jsdom",
setupFilesAfterFramework: ["/jest.setup.ts"],
});
```
### 4.9 Kiểm Tra Tổng Quát
- [ ] Chạy `npm audit` sau khi upgrade tất cả packages
```bash
npm audit
npm audit fix
```
- [ ] Kiểm tra `npm ls --depth=0` không có unmet peer dependencies
- [ ] Test build production
```bash
npm run build
```
- [ ] Kiểm tra bundle size không tăng đột biến
```bash
npx @next/bundle-analyzer
```
---
## 5. Testing Checklist Sau Migration
### 5.1 Build & Compile
- [ ] `npm run build` thành công không có errors
- [ ] Không có TypeScript errors: `npx tsc --noEmit`
- [ ] Không có ESLint errors: `npm run lint`
- [ ] Bundle size trong acceptable range
- [ ] Kiểm tra `.next/` directory được generate đúng
### 5.2 Development Server
- [ ] `npm run dev` khởi động thành công
- [ ] Hot Module Replacement (HMR) hoạt động
- [ ] Fast Refresh hoạt động khi edit components
- [ ] Không có warnings về deprecated APIs trong console
- [ ] Turbopack (nếu enable) không có compilation errors
### 5.3 Core Functionality Testing
- [ ] **Navigation:** Tất cả internal links hoạt động đúng
- [ ] **Dynamic routes:** `[slug]`, `[id]` params được resolve đúng
- [ ] **Catch-all routes:** `[...slug]` hoạt động
- [ ] **Query params:** `searchParams` được đọc đúng
- [ ] **Redirects & Rewrites:** Kiểm tra `next.config.js` redirects
- [ ] **Middleware:** Authentication, i18n middleware hoạt động
### 5.4 Data Fetching Testing
- [ ] Server Components fetch data thành công
- [ ] Cache/revalidate hoạt động đúng
- [ ] `revalidatePath()` trigger đúng
- [ ] `revalidateTag()` trigger đúng
- [ ] ISR (Incremental Static Regeneration) hoạt động
- [ ] Static pages được generate đúng
### 5.5 Forms & Mutations
- [ ] Server Actions submit thành công
- [ ] `useActionState` hiển thị đúng states (idle, pending, success, error)
- [ ] `useFormStatus` hoạt động đúng
- [ ] Form validation errors hiển thị đúng
- [ ] Optimistic updates (nếu có) hoạt động
### 5.6 Authentication Flow
- [ ] Login flow hoạt động
- [ ] Logout flow hoạt động
- [ ] Protected routes redirect đúng
- [ ] Session persistence hoạt động
- [ ] Cookie handling với async `cookies()` đúng
### 5.7 UI/UX Testing
- [ ] Tất cả pages render đúng layout
- [ ] Loading states hiển thị đúng
- [ ] Error boundaries hoạt động
- [ ] Responsive design không bị ảnh hưởng
- [ ] Dark/Light mode (nếu có) hoạt động
- [ ] Animations (Framer Motion, etc.) hoạt động mượt mà
- [ ] Images load đúng với `next/image`
- [ ] Fonts load đúng với `next/font`
### 5.8 Performance Testing
- [ ] Chạy Lighthouse audit trên production build
```bash
npx lighthouse https://your-site.com --view
```
- [ ] Kiểm tra Core Web Vitals không giảm
- [ ] **LCP** (Largest Contentful Paint) < 2.5s
- [ ] **FID/INP** (Interaction to Next Paint) < 200ms
- [ ] **CLS** (Cumulative Layout Shift) < 0.1
- [ ] Kiểm tra không có memory leaks
- [ ] Server response time trong acceptable range
### 5.9 SEO Testing
- [ ] Meta tags render đúng (title, description)
- [ ] Open Graph tags hoạt động
- [ ] `robots.txt` accessible
- [ ] `sitemap.xml` generated đúng
- [ ] Canonical URLs đúng
- [ ] Structured data (JSON-LD) không bị ảnh hưởng
### 5.10 Automated Tests
- [ ] Tất cả unit tests PASS
```bash
npm run test
```
- [ ] Integration tests PASS
- [ ] E2E tests PASS
```bash
npm run test:e2e
```
- [ ] Test coverage không giảm so với trước migration
- [ ] Snapshot tests được update
```bash
npm run test -- --updateSnapshot
```
### 5.11 Cross-browser Testing
- [ ] Chrome (latest)
- [ ] Firefox (latest)
- [ ] Safari (latest) — đặc biệt quan trọng với iOS
- [ ] Edge (latest)
- [ ] Mobile browsers (iOS Safari, Chrome Android)
### 5.12 Production Deployment Checklist
- [ ] Environment variables đã được set đúng
- [ ] Build production thành công trong CI/CD
- [ ] Database migrations (nếu có) đã chạy
- [ ] CDN cache invalidated
- [ ] Monitoring/alerting setup kiểm tra OK
- [ ] Rollback plan đã chuẩn bị
- [ ] Deploy to staging trước, test xong mới production
- [ ] Post-deployment smoke tests
---
## Tài Liệu Tham Khảo
| Tài liệu | Link |
|---|---|
| Next.js 15 Migration Guide | [nextjs.org/docs/upgrading](https://nextjs.org/docs/upgrading) |
| React 19 Upgrade Guide | [react.dev/blog/2024/04/25/react-19-upgrade-guide](https://react.dev/blog/2024/04/25/react-19-upgrade-guide) |
| Next.js Codemods | [nextjs.org/docs/app/building-your-application/upgrading/codemods](https://nextjs.org/docs/app/building-your-application/upgrading/codemods) |
| React 19 Blog Post | [react.dev/blog/2024/12/05/react-19](https://react.dev/blog/2024/12/05/react-19) |
| Next.js 15 Release Notes | [nextjs.org/blog/next-15](https://nextjs.org/blog/next-15) |
---
## Lệnh Codemod Tổng Hợp
```bash
# Chạy tất cả codemods cần thiết (khuyến nghị)
npx @next/codemod@canary upgrade latest
# Hoặc chạy từng codemod riêng lẻ
npx @next/codemod@canary next-async-request-api . # async params, cookies, headers
npx @next/codemod@canary next-comp-link-passthrough-ref . # forwardRef → ref prop
npx @next/codemod@canary new-link . # →
npx @next/codemod@canary next-og-import . # OG image imports
```
---
> **💡 Tips:**
> - Migrate từng breaking change một, commit sau mỗi bước để dễ debug
> - Dùng `git bisect` nếu có regression khó tìm
> - Enable React 19 strict mode để phát hiện sớm deprecated patterns
> - Theo dõi [Next.js GitHub Discussions](https://github.com/vercel/next.js/discussions) để cập nhật issues mới nhất