The dashboard uses small TypeScript dictionaries, one file per language.
src/i18n/
├── en.ts # source keys and English text
├── it.ts # Italian
├── fr.ts # French
├── es.ts # Spanish
├── de.ts # German
├── zh.ts # Chinese
└── translations.ts # language registry
en.ts is the source of truth for translation keys. Other languages are typed as Record<keyof typeof en, string>, so TypeScript fails if a language is missing a key.
- Find the key in
src/i18n/en.ts. - Update the same key in each language file that needs a wording change.
- Keep placeholders unchanged. For example, if English contains
{count}or{time}, every translation for that key must keep the same placeholder name. - Run:
npm run typecheck
npm testExample:
"common.refresh": "Refresh",can become:
"common.refresh": "Reload",Do not rename the key unless you also update every t("...") call that uses it.
- Add the key to
src/i18n/en.ts. - Add the same key to every other language file.
- Use the key from React with
t("your.key").
Example:
// src/i18n/en.ts
"repo.lastSeen": "Last seen {time}",const { t } = useI18n();
return <span>{t("repo.lastSeen", { time: "10m ago" })}</span>;Interpolation is intentionally simple: values are replaced by matching {name} tokens.
Use a lowercase language code as the file name. For example, Portuguese would use pt.ts.
- Copy
src/i18n/en.tstosrc/i18n/pt.ts. - Rename the export and add the type constraint:
import type { en } from "./en";
export const pt: Record<keyof typeof en, string> = {
"app.title": "Gitdeck",
// ...
};- Translate the values. Keep all keys and placeholders unchanged.
- Register the language in
src/i18n/translations.ts:
import { pt } from "./pt";
export const translations = { en, it, fr, es, de, zh, pt } as const;- Add the language name to every dictionary:
"language.pt": "Português",- If the language needs custom relative-time text, update
RELATIVE_TIME_LABELSinsrc/utils/format.ts. - Add or update tests in:
tests/utils/i18n.test.ts
tests/utils/format.test.ts
- Run:
npm run typecheck
npm test
npm run build- The new file is listed in
src/i18n/translations.ts. npm run typecheckpasses.- All placeholders match the English source.
- The language appears in the top-bar language switcher.
- Browser language detection works for the language code.
- Relative time is readable in list rows and repository cards.