App Router không có i18n config sẵn như Pages Router; bạn dựng routing bằng dynamic segment [locale] + middleware để phát hiện/redirect ngôn ngữ.
app/[locale]/layout.tsx
app/[locale]/page.tsxMiddleware đọc Accept-Language hoặc cookie, redirect / → /vi. generateStaticParams liệt kê các locale để build tĩnh.
next-intl xây sẵn lớp này và bổ sung:
- Middleware locale-detection + routing cấu hình sẵn (prefix /vi, /en).
- API dịch dùng được trong Server Components: getTranslations() (async, server) và useTranslations() (client) — quan trọng vì hầu hết i18n lib cũ chỉ chạy client.
- Format số/ngày/plural theo Intl chuẩn, type-safe message keys.
import { useTranslations } from 'next-intl'
function Title() {
const t = useTranslations('Home')
return <h1>{t('title')}</h1>
}Lưu ý: giữ message ở Server Component khi có thể để không gửi toàn bộ từ điển xuống client — chỉ Client Component nào cần mới nhận phần của nó.