2.1 KiB
2.1 KiB
i18n (Thai / English)
LCBP3 frontend must not hardcode Thai or English UI strings in components.
Rules
- All user-facing strings go through the i18n layer (
next-intl/i18next— checkfrontend/package.json). - Keys use kebab-case, namespaced by feature:
correspondence.list.titlecorrespondence.form.submitcommon.actions.cancel
- Comments in code remain Thai (business logic explanation); only UI copy goes through i18n.
- Error messages from backend (via ADR-007
userMessage) are already localized server-side — render them directly, don't translate client-side.
❌ Wrong
export function CorrespondenceHeader() {
return <h1>รายการหนังสือติดต่อ</h1>; // ❌ hardcoded Thai
}
toast.success('บันทึกสำเร็จ'); // ❌ hardcoded
✅ Right
import { useTranslations } from 'next-intl';
export function CorrespondenceHeader() {
const t = useTranslations('correspondence.list');
return <h1>{t('title')}</h1>;
}
toast.success(t('save.success'));
Translation files:
// messages/th.json
{
"correspondence": {
"list": { "title": "รายการหนังสือติดต่อ" },
"save": { "success": "บันทึกสำเร็จ" }
}
}
// messages/en.json
{
"correspondence": {
"list": { "title": "Correspondence List" },
"save": { "success": "Saved successfully" }
}
}
Zod Error Messages
Zod error messages shown in forms do stay in Thai inline (per specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md), because they're schema-bound and rarely need translation. If dual-language support becomes required, wrap with an i18n-aware resolver:
const schema = z.object({
projectUuid: z.string().uuid(t('validation.project.required')),
});