# Internationalization (i18n)

## Overview

PWA Kit applications use React Intl for internationalization and localization. The system supports multiple locales, currency formats, date formats, and translated messages.

## React Intl Integration

```jsx
import {IntlProvider, FormattedMessage, FormattedNumber, FormattedDate} from 'react-intl';
```

## Translation Files

Translations live at project root; compiled output goes to `app/static/translations/compiled/`:

```
project-root/
├── translations/
│   ├── en-US.json
│   ├── en-GB.json
│   └── fr-FR.json
└── app/
    └── static/
        └── translations/
            └── compiled/
                ├── en-US.json
                ├── en-GB.json
                └── en-XA.json   # pseudo-locale for testing
```

### Message Format

```json
{
    "product.add_to_cart": "Add to Cart",
    "product.price": "Price: {price}",
    "cart.item_count": "{count, plural, =0 {No items} one {1 item} other {# items}}"
}
```

## Defining Messages

### Using defineMessage

```jsx
import {defineMessage, useIntl} from 'react-intl';
import {Button} from '@salesforce/retail-react-app/app/components/shared/ui';

const messages = {
    addToCart: defineMessage({
        id: 'product.add_to_cart',
        defaultMessage: 'Add to Cart'
    })
};

const ProductTile = ({product}) => {
    const intl = useIntl();
    return (
        <Button>{intl.formatMessage(messages.addToCart)}</Button>
    );
};
```

### Using FormattedMessage

```jsx
import {FormattedMessage} from 'react-intl';

<FormattedMessage
    id="product.add_to_cart"
    defaultMessage="Add to Cart"
/>
```

## Message Formatting

### With Variables

```jsx
<FormattedMessage
    id="product.price"
    defaultMessage="Price: {price}"
    values={{price: product.price}}
/>
```

### Pluralization

```jsx
<FormattedMessage
    id="cart.item_count"
    defaultMessage="{count, plural, =0 {No items} one {1 item} other {# items}}"
    values={{count: itemCount}}
/>
```

### Date and Number Formatting

```jsx
import {FormattedDate, FormattedNumber} from 'react-intl';

<FormattedDate
    value={new Date()}
    year="numeric"
    month="long"
    day="numeric"
/>

<FormattedNumber
    value={product.price}
    style="currency"
    currency="USD"
/>
```

## useIntl Hook

```jsx
import {useIntl} from 'react-intl';
import {Text} from '@salesforce/retail-react-app/app/components/shared/ui';

const ProductDetail = ({product}) => {
    const intl = useIntl();

    const formattedPrice = intl.formatNumber(product.price, {
        style: 'currency',
        currency: 'USD'
    });

    return <Text>{formattedPrice}</Text>;
};
```

## Translation Extraction

```bash
# Extract default messages (en-US, en-GB)
npm run extract-default-translations

# Compile translations
npm run compile-translations

# Compile pseudo-locale for testing
npm run compile-translations:pseudo
```

## Multi-Locale Configuration

Sites and locales are defined in `config/sites.js`:

```javascript
// config/sites.js
module.exports = [
    {
        id: 'RefArch',
        l10n: {
            supportedCurrencies: ['USD'],
            defaultCurrency: 'USD',
            defaultLocale: 'en-US',
            supportedLocales: [
                { id: 'en-US', preferredCurrency: 'USD' },
                { id: 'en-CA', preferredCurrency: 'USD' }
            ]
        }
    }
];
```

## Locale Switcher

```jsx
import {useIntl} from 'react-intl';
import {useHistory, useLocation} from 'react-router-dom';
import {Select} from '@salesforce/retail-react-app/app/components/shared/ui';

const LocaleSwitcher = ({supportedLocales}) => {
    const intl = useIntl();
    const history = useHistory();
    const location = useLocation();

    const handleChange = (e) => {
        const newLocale = e.target.value;
        const newPath = location.pathname.replace(
            `/${intl.locale}/`,
            `/${newLocale}/`
        );
        history.push(newPath);
    };

    return (
        <Select value={intl.locale} onChange={handleChange}>
            {supportedLocales.map((locale) => (
                <option key={locale.id} value={locale.id}>
                    {locale.id}
                </option>
            ))}
        </Select>
    );
};
```

## Best Practices

1. Always use translation keys
2. Provide defaultMessage
3. Use semantic key names
4. Extract regularly
5. Compile for production
6. Test with pseudo-locale
7. Consider text expansion
8. Format dates and numbers
9. Handle pluralization
10. Document context
