Translation Guide
Adding a new language
- Copy
locales/en-US.jsontolocales/<code>.json(e.g.ja-JP.json) - Append an entry to the end of the
supportedLocalesarray inlocales.ts— do not reorder existing entries, as the first locale for each language prefix (e.g.zh-CNforzh) is used as the default when the browser sends a bare language code:{ code: 'ja-JP', label: '日本語', shortLabel: 'JA' }, - Translate all values in the new JSON file. Keys must remain identical.
Interpolation
This project uses i18next with the default double-brace syntax: {{variable}}.
Example: "Hi, {{name}}" will render as "Hi, Alice" when called with t('key', { name: 'Alice' }).
Do NOT remove or rename interpolation variables — they are referenced in code.
Keys with design intent
Not every key needs explanation, but the following have non-obvious UX context that affects how they should be translated.
| Key | Where it appears | Translation notes |
|---|---|---|
home.greetingWithName |
Top-left of homepage, clickable pill that opens nickname editor | This is a call-to-action — the greeting doubles as an entry point for users to set their nickname. The translation must include {{name}} and read naturally with the default nickname (see profile.defaultNickname). Avoid generic greetings that hide the name (e.g. don't translate as just "Welcome"). |
profile.defaultNickname |
Pre-filled in the greeting and the nickname input field | Shown before the user sets a real name. Pick a warm, gender-neutral word that: (1) feels natural in the greeting, (2) clearly signals "this is a placeholder you should replace". Avoid cold terms like "User" or formal terms like "Student". Examples: EN "Learner", ZH "同学". |
profile.bioPlaceholder |
Textarea placeholder in the profile editor | The bio is fed to the AI teacher to personalize lessons. The placeholder should hint at this — tell users why filling it in helps. |
pbl.chat.issueCompleteMessage |
System message when a PBL issue is completed | Contains {{completed}} and {{next}}. Should feel like a natural progression, not a mechanical status update. |
generation.textTruncated / generation.imageTruncated |
Toast warnings during PDF-based course generation | These are technical warnings shown briefly. Keep them short and factual. textTruncated has {{n}} (character count), imageTruncated has {{total}} and {{max}}. |
agentBar.readyToLearn |
Classroom page, above the agent role list | Conversational prompt to set the mood before class starts. Should feel inviting, not instructional. |
settings.agentsCollaboratingCount |
Settings panel, multi-agent mode description | Contains {{count}}. This is a status label, not a button — keep it descriptive. |