# Internationalization (i18n)

## Overview

- **Server instance**: Has access to all translations for all languages
- **Client instance**: Dynamically imports translations as JavaScript chunks
- **Dual API**: `useTranslation()` for components, `getTranslation()` for everything else

## Adding Translations

**In `src/locales/{language}/translations.json`**:

```json
{
  "product": {
    "title": "Product Details",
    "addToCart": "Add to Cart",
    "greeting": "Hello, {{name}}!",
    "itemCount": {
      "zero": "No items",
      "one": "{{count}} item",
      "other": "{{count}} items"
    }
  }
}
```

## Usage

**2. Use in React components:**

```typescript
import { useTranslation } from 'react-i18next';

export function ProductCard() {
    const { t } = useTranslation('product');

    return (
        <div>
            <h1>{t('title')}</h1>
            <button>{t('addToCart')}</button>
            <p>{t('greeting', { name: 'John' })}</p>
            <p>{t('itemCount', { count: 5 })}</p>
        </div>
    );
}
```

**3. Use in non-component code:**

```typescript
import { getTranslation } from '@/lib/i18next';

// Client-side or utilities
const { t } = getTranslation();
const message = t('product:addToCart');

// Server-side (loaders/actions)
export function loader(args: LoaderFunctionArgs) {
    const { t } = getTranslation(args.context);
    return { title: t('product:title') };
}
```

## Validation Schemas with Translations

**CRITICAL**: Use factory pattern for Zod schemas to avoid race conditions:

```typescript
// ❌ WRONG - Module-level schema (race condition)
export const schema = z.object({
    email: z.string().email(t('validation:emailInvalid'))
});

// ✅ CORRECT - Factory function
import type { TFunction } from 'i18next';

export const createSchema = (t: TFunction) => {
    return z.object({
        email: z.string().email(t('validation:emailInvalid'))
    });
};

// Usage in component
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';

function MyForm() {
    const { t } = useTranslation();
    const schema = useMemo(() => createSchema(t), [t]);

    const form = useForm({ resolver: zodResolver(schema) });
}
```

## Language Switching

```typescript
import LocaleSwitcher from '@/components/locale-switcher';

export function Footer() {
    return <footer><LocaleSwitcher /></footer>;
}
```

## Extension Translations

Extensions use `extPascalCase` namespace:

```
src/extensions/my-extension/locales/
├── en-US/translations.json
└── it-IT/translations.json
```

```typescript
const {t} = useTranslation('extMyExtension');
t('welcome');
```

**Reference:** See README-I18N.md for complete internationalization documentation.
