skills/internationalization/SKILL.md
i18n patterns for this project — useLocale/useLanguage/useCurrentLang hooks, URL-based language routing, adding translation keys, SupportedLanguageType. Use when adding UI text, building localized links, or working with language switching.
npx skillsauth add bkinsey808/songshare-effect internationalizationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Requires: file-read, terminal (linting/testing). No network access needed.
Use this skill when:
Execution workflow:
useLocale default for UI).npm run lint.Output requirements:
The project uses react-i18next with URL-path-based language routing. The active language lives in the URL — /en/songs, /es/songs, /zh/songs.
Supported languages are defined in @/shared/language/supported-languages:
// Supported values: "en" | "es" | "zh"
import type { SupportedLanguageType } from "@/shared/language/supported-languages";
| Hook | Returns | Use when |
| ------------------ | ------------- | --------------------------------------------------------------------------------------------------- |
| useLocale() | { lang, t } | Component needs both language and translation function |
| useLanguage() | lang | Component needs language only (e.g., building locale-aware URLs) |
| useCurrentLang() | lang | Need lang from URL pathname without component reactivity (or in tests with { pathname } override) |
Default: useLocale() — it's the most ergonomic for UI components.
import useLocale from "@/react/lib/language/locale/useLocale";
function MySongCard(): ReactElement {
const { t, lang } = useLocale();
return (
<div>
<p>{t("songs.by_artist")}</p>
<a href={`/${lang}/songs`}>{t("nav.songs")}</a>
</div>
);
}
Translations live in react/src/translations/:
react/src/translations/
├── en.json
├── es.json
└── zh.json
Add the key to all three files:
// en.json
{ "songs": { "by_artist": "By Artist" } }
// es.json
{ "songs": { "by_artist": "Por Artista" } }
// zh.json
{ "songs": { "by_artist": "按艺术家" } }
Use dot notation in t():
t("songs.by_artist");
Always prefix routes with /${lang}/ — never hardcode /en/ or /:
// ✅ GOOD
const { lang } = useLocale();
<Link to={`/${lang}/community/${communityId}`}>...</Link>
// ❌ BAD
<Link to={`/en/community/${communityId}`}>...</Link>
<Link to={`/community/${communityId}`}>...</Link>
To switch language while staying on the same page, use getPathWithoutLang from @/react/lib/language/path/getPathWithoutLang:
import getPathWithoutLang from "@/react/lib/language/path/getPathWithoutLang";
const pathWithoutLang = getPathWithoutLang(location.pathname);
navigate(`/${newLang}${pathWithoutLang}`);
Use the pure utility getCurrentLangFromPath when you need the language outside a React component or in tests:
import getCurrentLangFromPath from "@/react/lib/language/path/getCurrentLangFromPath";
const lang = getCurrentLangFromPath("/es/songs"); // → "es"
const lang = getCurrentLangFromPath("/zz/foo"); // → "en" (falls back to defaultLanguage)
LanguageProvider from @/react/lib/language/provider/LanguageProvider is mounted near the root. It syncs the i18next runtime language with the URL. Do not call i18n.changeLanguage() directly — let the provider handle it.
t("key")i18n directly from @/react/lib/language/i18n in components — use useLocale() / useTranslation()@/shared/language/supported-languagesreact-best-practices.naming-conventions.tools
Zustand state management patterns for this project — store creation, selectors, Immer middleware, async actions with loading states, devtools, persist, and testing. Use when authoring or editing Zustand stores (use*Store files) or components that subscribe to stores. Do NOT use for React component structure or TypeScript-only utilities.
testing
How to write, update, or split skill files in this repo. Use when creating a new SKILL.md, updating an existing one, or deciding whether to put content in a skill vs. docs/.
development
Complete guide for testing React hooks — renderHook, Documentation by Harness, installStore, fixtures, subscription patterns, lint/compiler traps, and pre-completion checklist. Read docs/testing/unit-test-hook-best-practices.md for the full reference.
development
Vitest unit test authoring for this repo — setup, mocking, API handler testing, and common pitfalls for non-hook code. Use when the user asks to add, update, fix, or review unit tests for utilities, components, API handlers, or scripts. Do NOT use for React hook tests — load unit-test-hook-best-practices instead.