Prompt file imported from ZACK770/studytoy (
.windsurf/workflows/i18n-guidelines.md). Copyright stays with the author.
i18n Guidelines
Setup in Every Component
import { useTranslation } from 'react-i18next'
export default function MyComponent() {
const { t, i18n } = useTranslation()
Rules
- No hardcoded UI text — every user-visible string goes through
t(). - No emojis — use Lucide icons instead.
- Do not translate user-generated content (game names, descriptions, comments, etc.).
- Every new key must be added to both JSON files:
frontend/src/i18n/locales/en.json(English — also the fallback)frontend/src/i18n/locales/he.json(Hebrew)
- Key naming:
namespace.keyName, e.g.settings.title,settings.saveBtn. - Static label arrays — use
labelKeyinstead of inline strings:const TABS = [{ labelKey: 'nav.settings' }, { labelKey: 'nav.profile' }] // In JSX: {t(tab.labelKey)} - Dynamic values — use interpolation:
t('common.level', { level: 5 }) // "Level 5" / "רמה 5" - RTL/LTR — standalone pages/modals should set:
Components insidedir={i18n.language === 'he' ? 'rtl' : 'ltr'}AppShellinherit direction automatically.
Fallback Behavior
fallbackLngis set to'en'infrontend/src/i18n/index.ts.- If a translation key is missing, English text is shown automatically.
Workflow
Write component → Add keys to en.json + he.json → Verify build (npx tsc --noEmit)
Adding a New Language
- Copy
en.jsonto a new file, e.g.ar.json. - Translate all values (keep keys unchanged).
- Register in
frontend/src/i18n/index.ts:import ar from './locales/ar.json' // In resources: ar: { translation: ar }, // In supportedLngs: supportedLngs: ['he', 'en', 'ar'], - For RTL languages, update the direction check:
const dir = ['he', 'ar'].includes(lng) ? 'rtl' : 'ltr'
