Files
lcbp3/.agents/skills/next-best-practices/i18n.md
T
admin a57fef4d44
CI / CD Pipeline / build (push) Successful in 5m51s
CI / CD Pipeline / deploy (push) Successful in 2m9s
690427:0812 Update Infras #01
2026-04-27 08:12:28 +07:00

2.1 KiB

i18n (Thai / English)

LCBP3 frontend must not hardcode Thai or English UI strings in components.

Rules

  1. All user-facing strings go through the i18n layer (next-intl / i18next — check frontend/package.json).
  2. Keys use kebab-case, namespaced by feature:
    • correspondence.list.title
    • correspondence.form.submit
    • common.actions.cancel
  3. Comments in code remain Thai (business logic explanation); only UI copy goes through i18n.
  4. 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')),
});

Reference