| name | biz-i18n-landing-page |
| description | Thêm đa ngôn ngữ (i18n) cho landing page Next.js đã build sẵn — biến trang viết bằng 1 ngôn ngữ thành trang đa ngôn ngữ với nút pill chuyển ngôn ngữ cố định góc trên bên phải, đổi tức thì không reload không đổi URL. Workflow 8 phase: (0) detect Next.js App Router project trong output/ — TS/Tailwind/src wrapper/path alias @/, hỏi user chọn nếu có nhiều landing page; (1) **PHỎNG VẤN user qua AskUserQuestion**: hỏi muốn hỗ trợ ngôn ngữ nào (gợi ý Tiếng Việt / English / 中文 / 한국어 — và Other cho 日本語, Thái...) và ngôn ngữ nào làm mặc định hiện khi mới vào trang; (2) quét toàn bộ copy hardcode trong app/page.tsx + mọi component con (Hero/Pricing/FAQ/Footer/form...) + metadata layout.tsx, gom thành dictionary key theo section; (3) **tự dịch** sang mọi ngôn ngữ đã chọn — bản địa hoá marketing chứ không dịch máy, giữ nguyên tên brand + giá VND + SĐT + URL; (4) scaffold hệ thống i18n client-side trong app/i18n/ — React Context + JSON dictionaries + localStorage + auto-detect ngôn ngữ trình duyệt, KHÔNG đổi URL, KHÔNG đụng app/api hay app/admin, KHÔNG thêm dependency; (5) gắn LanguageProvider vào layout.tsx + render LanguageSwitcher pill + rewire mỗi component dùng hook useT() thay text hardcode; (6) chạy npm run build verify trang ngôn ngữ gốc hiển thị y hệt trước; (7) báo cáo + gợi ý deploy lại qua /biz-deploy-vercel. File ngôn ngữ gốc (vi.ts) làm source-of-truth type nên TypeScript bắt lỗi nếu thiếu key dịch. USE WHEN user says 'làm landing page đa ngôn ngữ', 'thêm i18n', 'website nhiều ngôn ngữ', 'dịch landing page sang tiếng Anh', 'song ngữ Việt Anh', 'nút chuyển ngôn ngữ', 'language switcher', 'multilingual landing page', 'add i18n to website', 'translate landing page', 'biz-i18n', 'hỗ trợ tiếng Trung tiếng Hàn cho web', 'cho khách nước ngoài xem được trang', 'thêm tiếng Anh vào trang'. Dùng skill này BẤT CỨ KHI NÀO user muốn trang web hiển thị được nhiều hơn 1 ngôn ngữ — kể cả khi chỉ nói 'cho khách Tây đọc được' hay 'web em mới có tiếng Việt thôi'. Skill KHÔNG dịch chatbot / email auto-responder / admin dashboard — các hệ thống đó có cơ chế riêng; skill chỉ lo copy hiển thị trên landing page. |
| framework | Next.js 13+ App Router — i18n client-side (React Context + JSON dictionaries) — không thêm dependency — Tailwind cho nút switcher |
biz-i18n-landing-page
Biến một landing page Next.js đang viết bằng 1 ngôn ngữ thành trang đa
ngôn ngữ. Visitor thấy một nút pill nhỏ cố định ở góc trên bên phải — bấm
là đổi ngôn ngữ ngay tức thì, không reload, không đổi URL. Lựa chọn được nhớ
qua localStorage, và lần đầu vào trang skill tự đoán theo ngôn ngữ trình
duyệt.
Skill này chạy sau khi landing page đã build (qua ui-ux-pro-max). Chạy
trước hay sau /biz-deploy-vercel đều được — nếu trang đã deploy thì cuối
cùng deploy lại.
Vì sao client-side, không dùng locale routing
Landing page ở repo này là một URL duy nhất đã sở hữu sẵn app/api/,
app/admin/, app/cam-on/... Đi theo hướng locale routing (app/[locale]/ +
middleware) sẽ phải dời mọi route vào dưới [locale] — một thay đổi nặng và
rủi ro cho một trang bán hàng một-trang. Thay vào đó ngôn ngữ sống trong React
state: nhẹ, không thêm dependency, không phá vỡ route nào, và đúng trải nghiệm
"bấm nút là đổi" mà trang bán hàng cần. Đánh đổi duy nhất: mỗi ngôn ngữ không
có URL riêng cho SEO — chấp nhận được với trang chạy traffic quảng cáo.
Cấu trúc i18n sinh ra
app/i18n/ (hoặc src/app/i18n/ nếu project dùng src/)
├── dictionaries/
│ ├── vi.ts ← source of truth: copy gốc nguyên văn, định nghĩa SHAPE
│ ├── en.ts ← bản dịch — typed là Dictionary, phải khớp key với vi.ts
│ └── index.ts ← registry: dictionaries, locales, defaultLocale, localeNames
├── LanguageContext.tsx ← Provider + hook useT() / useLanguage()
└── LanguageSwitcher.tsx ← nút pill cố định góc trên phải
Mọi file template nằm ở templates/. LanguageContext.tsx và
LanguageSwitcher.tsx copy gần như nguyên văn; index.ts và các file
dictionary thì điền nội dung thật.
Quy trình — 8 phase
Phase 0 — Detect project
Tìm landing page cần xử lý. Trang Next.js nằm trong output/<slug>/ (thường
là output/<slug>/landing-page/) — nhận diện qua sự tồn tại của app/page.tsx
hoặc src/app/page.tsx.
- Nếu có nhiều landing page → dùng
AskUserQuestion hỏi user chọn project.
- Detect và ghi nhớ: dùng TypeScript (
tsconfig.json) hay JS; có wrapper
src/ không; có Tailwind không; có path alias @/ không ( →
). Xác nhận là App Router (có ).