# Internationalization

### Install dependencies

To use i18next with React and the specified plugins, you need to install the following dependencies:&#x20;

* **i18next**: The core internationalization library.

  ```bash
  yarn add i18next
  ```
* **react-i18next**: The React bindings for i18next.

  ```bash
  yarn add react-i18next
  ```
* **i18next-browser-languagedetector**: A language detector for the browser.

  ```bash
  yarn add i18next-browser-languagedetector
  ```
* **i18next-http-backend**: A backend for loading translations via HTTP.

  ```bash
  yarn add i18next-http-backend
  ```

### Initialize i18next

This code initializes `i18next`, setting up internationalization with several configurations:

* `.use(initReactI18next)`: Initializes i18next for React, providing React-specific features.
* `.use(I18nextBrowserLanguageDetector)`: Adds automatic browser-based language detection, which selects the user's language based on their browser settings.
* `.use(I18NextHttpBackend)`: Configures the backend to load translation files from an HTTP endpoint, specified in the `loadPath` of the main `init` configuration.

***

* `fallbackLng: 'en'`: English is the default language if no preference is detected.
* `load: 'languageOnly'`: Only the base language (e.g., `en`) is loaded, without region variants.
* `supportedLngs: ['en', 'uk']`: Supports English and Ukrainian.
* `backend.loadPath`: Specifies the path to translation JSON files for language and namespace.
* `defaultNS: 'common'`: Sets the default namespace.
* `useSuspense: false`: Disables suspense in React for smoother integration without loading delays.

```javascript
import i18next from 'i18next';
import { initReactI18next } from 'react-i18next';
import I18nextBrowserLanguageDetector from 'i18next-browser-languagedetector';
import I18NextHttpBackend from 'i18next-http-backend';

i18next
    .use(initReactI18next)
    .use(I18nextBrowserLanguageDetector)
    .use(I18NextHttpBackend)
    .init({
        fallbackLng: 'en',
        load: 'languageOnly',
        supportedLngs: ['en', 'uk'],
        interpolation: {
            escapeValue: false,
        },
        backend: {
            loadPath: '/locales/{{lng}}/{{ns}}.json',
        },
        react: {
            useSuspense: false,
        },
        defaultNS: 'common',
    });
```

### Directory Structure ( Resource setup )

1. **Create `locales` Directory**\
   Inside the `public` folder of your UI, create a directory named `locales`.
2. **Language Directories**\
   Within the `locales` directory, create separate directories for each language you will support, using abbreviations such as:
   * `uk` for Ukrainian
   * `en` for English
3. **Resource Files**\
   Inside each language directory, create a JSON file with resource name like `general.json`. Populate these files with structured translations.

#### English (`en/general.json`)

```json
{
    "home": "Home",
    "dashboard": "Dashboard",
    "settings": "Settings",
    "search": "Search",
    "language": "Language",
    "error": "Error",
    "success": "Success",
    "none": "None",
    "or": "Or",
    "field": "field"
}
```

#### Ukrainian (`uk/general.json`)

```json
{
    "home": "Головна",
    "dashboard": "Панель управління",
    "settings": "Налаштування",
    "search": "Пошук",
    "language": "Мова",
    "error": "Помилка",
    "success": "Операція успішна",
    "none": "Немає",
    "or": "Або",
    "field": "поле"
}
```

### Notifications configuration

The `requestNotification` method is designed to trigger notifications with dynamic content based on a set of parameters:

* **Parameters**: It takes an object with keys `type` (notification type), `resource` (subject), `action` (performed action), and `plural` (boolean for noun plurality).
* **Message Structure**: Based on `plural`, it selects either the singular or plural form of the resource (`resourceI18n`).
* **API Call**: The notification API is called with a title and a description, both localized with `i18next`. The description includes `resource`, `noun`, and `action`, where the action is continuous and lowercase.

This setup ensures adaptable, internationalized notifications for various actions and resources.

```javascript
const requestNotification = ({ type, resource, action, plural }) => {
    const nounType = plural ? 'plural' : 'singular';

    const resourceI18n = t(`notifications:resources.${resource}.${nounType}`);

    api[type]({
        message: t(`general:${type}`),
        description: t(`notifications:${type}`, {
            resource: resourceI18n,
            noun: t(`notifications:noun.${nounType}`),
            action: t(`general:actions.continuous.${action}`).toLowerCase(),
        }),
        placement: 'top',
    });
};
```

### UI Usage

1. Import `useTranslation` hook for `react-i18next` library

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

2. Initialize translations variable in your component

```javascript
const { t } = useTranslation(['dashboard']);
```

3. Use your translations by providing translation path and name

```javascript
t('placeholders.businesses')
```

{% hint style="info" %}
If you are importing more than one resource, use the following syntax:

```javascript
useTranslation(['users', 'general', 'confirmModal', 'apiResponses']);
```

The first resource will be selected automatically with every usage. For example:

```javascript
t('placeholders.businesses'); // This will resolve to users:placeholder.businesses
```

To use a different resource, provide the resource name followed by a colon (`:`):

```javascript
t('general:statuses.active');
```

This format allows for easy access to keys from multiple translation files.
{% endhint %}

### API Usage

1. Create the `apiResponses` translations file with the following content:

```json
{
    "EMAIL_NOT_FOUND": {
        "message": "To proceed, please sign up",
        "description": "You don't have any accounts yet."
    },
    "INCORRECT_CREDENTIALS": {
        "message": "Incorrect email or password",
        "description": "The email or password you entered is incorrect. Please try again or contact support if you are unable to access your account."
    },
    "EMAIL_EXISTS": {
        "message": "Error",
        "description": "A user with this email is already registered."
    }
}
```

2. When throwing exceptions, set the error code as follows:

```javascript
throw new HttpException(
    {
        message: 'Error',
        description: 'A user with this email is already registered.',
        code: 'EMAIL_EXISTS'
    },
    400
);
```

3. To manage API responses using the `openNotification` configuration, implement error handling as follows:

```javascript
catch (error) {
    const { code } = error.response.data;

    openNotification({
        type: notificationType.ERROR,
        message: code ? t(`apiResponses:${code}.message`) : t('notification.error.message'),
        description: code ? t(`apiResponses:${code}.description`) : t('notification.error.description'),
    });
}
```

***

{% embed url="<https://www.i18next.com/>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://intercode.gitbook.io/intercode-saas-kit/features/internationalization.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
