2.9 KiB
2.9 KiB
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/:
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 thescreenId).
Editing existing copy
- Find the bundle: search
messages/en/for the existing English string. - Edit the value. Leave the key alone.
- 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
- Decide which bundle owns the copy (page vs component vs common).
- Add a descriptive camelCase key. Group related copy in nested objects.
- If you created a new JSON file, register it in
messages/en/index.ts(a developer will help if you're unsure). - Reference the key from the component using
useMessages()(see the localization rule for the snippet).
{
"_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
_commentto leave context for the next editor. - Keep terminology consistent — search the messages folder before coining a new label.
Adding a new language (future)
- Create
messages/<locale>/mirroringmessages/en/. - Translate strings; keep keys identical.
- 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 |