Skip to content

Internationalization

PinTeach uses react-i18next for all user-facing strings. No hardcoded strings in components.

  • Primary language: Spanish (ES)
  • Secondary language: English (EN)
  • Total keys: 5,400+
import { useTranslation } from 'react-i18next';
function MyComponent() {
const { t } = useTranslation();
return (
<div>
<h1>{t('reviews.title')}</h1>
<p>{t('sessions.count', { count: 5 })}</p>
<button>{t('common.save')}</button>
</div>
);
}
Prefix Area
common.* Shared (save, cancel, delete, loading, error)
nav.* Navigation labels
dashboard.* Dashboard KPIs and actions
calendar.* Calendar views and events
sessions.* Session management
students.* Student CRM
services.* Service management
payments.* Payment history and KPIs
reviews.* Review system
materials.* Materials browser
widgets.* Widget configuration
settings.* Settings pages
shortcuts.* Keyboard shortcuts (55+ keys)
profile.* Teacher profile
auth.* Login and verification
onboarding.* Onboarding wizard
privacy.* GDPR and data management
  1. Every user-facing string must use t() — no hardcoded strings
  2. Both ES and EN translations are required for every key
  3. Use interpolation for dynamic values: t('key', { name: 'Maria' })
  4. Use pluralization: t('key', { count: n }) with _one / _other suffixes
  5. Keyboard shortcut labels use shortcuts.* namespace

Setup in apps/app/src/lib/i18n.ts:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
i18n.use(initReactI18next).init({
lng: 'es', // Spanish primary
fallbackLng: 'en',
interpolation: { escapeValue: false },
resources: { es, en },
});