Files
community-rule/docs/guides/i18n-translation-workflow.md
T
2026-04-18 14:12:49 -06:00

82 lines
2.9 KiB
Markdown

# Translations & UI copy workflow
This guide is for **content editors** updating user-visible text. The
implementation contract (file layout, `useMessages` access pattern, key
casing rules) lives in `.cursor/rules/localization.mdc`.
## Where copy lives
All UI text is JSON under `messages/en/`:
```text
messages/en/
common.json # shared strings (buttons, links, generic labels)
navigation.json # site nav items
metadata.json # page <title> / description
pages/<slug>.json # one file per page (home, learn, …)
components/<name>.json # one file per shared component default
create/<step>.json # one file per create-flow step
index.ts # wires all bundles together
```
The split is intentional:
- **`pages/`** — copy that varies by page context (titles, hero subheads).
- **`components/`** — defaults that ride along with a component on every
page (aria-labels, alt text patterns).
- **`common.json`** — strings reused across many components (e.g. "Cancel",
"Learn more").
- **`create/`** — wizard step copy (mirrors the `screenId`).
## Editing existing copy
1. Find the bundle: search `messages/en/` for the existing English string.
2. Edit the value. Leave the key alone.
3. Save and run `npm run dev` — text updates on reload.
If you can't find the string, it may still be hard-coded. Open an issue or
ping a developer; do not change the component file directly.
## Adding a new key
1. Decide which bundle owns the copy (page vs component vs common).
2. Add a descriptive camelCase key. Group related copy in nested objects.
3. If you created a new JSON file, register it in `messages/en/index.ts`
(a developer will help if you're unsure).
4. Reference the key from the component using `useMessages()` (see the
localization rule for the snippet).
```json
{
"_comment": "About page hero copy",
"hero": {
"title": "About us",
"subtitle": "Why CommunityRule exists"
}
}
```
## Style notes
- **camelCase** for structural keys (`compactTitle`, `imageAlt`).
- **kebab-case** for content ids that match a URL slug, card id, or step
id (`"in-person-meetings"`, `"peer-mediation"`).
- Use `_comment` to leave context for the next editor.
- Keep terminology consistent — search the messages folder before coining a
new label.
## Adding a new language (future)
1. Create `messages/<locale>/` mirroring `messages/en/`.
2. Translate strings; keep keys identical.
3. Update `messages/en/index.ts` (or split it per locale) — a developer
will wire the locale switcher.
## Troubleshooting
| Symptom | Likely cause | Fix |
| --- | --- | --- |
| Key path renders instead of text (e.g. `hero.title`) | Missing key or typo | Check spelling and bundle path |
| Copy doesn't update | Dev server cache | Restart `npm run dev` |
| TypeScript red squiggle | Bundle not registered | Add the import in `messages/en/index.ts` |