690427:0812 Update Infras #01
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# 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
|
||||
|
||||
```tsx
|
||||
export function CorrespondenceHeader() {
|
||||
return <h1>รายการหนังสือติดต่อ</h1>; // ❌ hardcoded Thai
|
||||
}
|
||||
|
||||
toast.success('บันทึกสำเร็จ'); // ❌ hardcoded
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Right
|
||||
|
||||
```tsx
|
||||
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:
|
||||
|
||||
```json
|
||||
// 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:
|
||||
|
||||
```ts
|
||||
const schema = z.object({
|
||||
projectUuid: z.string().uuid(t('validation.project.required')),
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reference
|
||||
|
||||
- [i18n Guidelines](../../../specs/05-Engineering-Guidelines/05-08-i18n-guidelines.md)
|
||||
- [Frontend Guidelines](../../../specs/05-Engineering-Guidelines/05-03-frontend-guidelines.md)
|
||||
Reference in New Issue
Block a user