66 lines
2.1 KiB
Plaintext
66 lines
2.1 KiB
Plaintext
---
|
|
description: Text localization via messages/ bundles and useMessages()
|
|
globs: messages/**/*.{ts,json}
|
|
alwaysApply: false
|
|
---
|
|
|
|
# Text localization
|
|
|
|
All user-visible copy lives in the typed messages bundle under `messages/en/`
|
|
and is read via `useMessages()` (fully typed) or `useTranslation()` (dot
|
|
notation). Never hard-code user-facing strings in components.
|
|
|
|
## File layout
|
|
|
|
- `messages/en/<area>.json` for single-file areas (`common.json`,
|
|
`navigation.json`, `metadata.json`).
|
|
- `messages/en/<folder>/<entry>.json` for areas with multiple buckets:
|
|
`components/*.json`, `pages/*.json`. One JSON per component / page —
|
|
don't shoehorn unrelated copy into a shared file.
|
|
- `messages/en/create/<stage>/<step>.json` — wizard steps grouped by Figma
|
|
stage (`community`, `customRule`, `reviewAndComplete`). Cross-cutting
|
|
chrome (footer, top nav, draft hydration, template review) and shared
|
|
layout-shell strings (`select.json`, `text.json`, `upload.json`) live at
|
|
the `create/` root.
|
|
- Optional `"_comment"` at the top of a JSON documents the bundle's purpose.
|
|
|
|
## Registration — required
|
|
|
|
Every new JSON must be wired into `messages/en/index.ts`:
|
|
|
|
```typescript
|
|
import createConflictManagement from "./create/customRule/conflictManagement.json";
|
|
|
|
export default {
|
|
// …
|
|
create: {
|
|
customRule: {
|
|
conflictManagement: createConflictManagement,
|
|
},
|
|
},
|
|
};
|
|
```
|
|
|
|
The default export **is** the type source for `useMessages()`; skipping this
|
|
step means consumers can't read your strings and TypeScript won't flag the gap.
|
|
|
|
## Access pattern
|
|
|
|
```typescript
|
|
import { useMessages } from "../contexts/MessagesContext";
|
|
|
|
const m = useMessages();
|
|
const title = m.create.customRule.conflictManagement.page.compactTitle; // fully typed
|
|
```
|
|
|
|
Use `useTranslation(namespace)` only when you need dot-path lookup by dynamic
|
|
key; prefer direct property access for the type safety.
|
|
|
|
## Key conventions
|
|
|
|
- **Structural keys**: camelCase (`compactTitle`,
|
|
`sectionHeadings.corePrinciple`).
|
|
- **Content ids**: match the id consumers already use (card id, step id, URL
|
|
segment) — typically kebab-case (`"in-person-meetings"`,
|
|
`"peer-mediation"`).
|