# i18n

The `@akinon/app-client` library provides built-in support for handling internationalization in your micro-frontend applications.&#x20;

### <mark style="color:red;">How It Works</mark>

1. Shell sets the current locale in shared data and broadcasts `LOCALE_CHANGED` events
2. Client receives the locale via `useAppClient().locale`
3. Client can subscribe to locale changes via `onLocaleChange`
4. Client updates its own i18n instance accordingly

### <mark style="color:red;">Accessing Current Locale</mark>

Use the `useAppClient` hook to access the current locale:

```tsx
import { useAppClient } from '@akinon/app-client';

const LocaleDisplay = () => {
  const { locale } = useAppClient();

  return <p>Current language: {locale}</p>;
};
```

### <mark style="color:red;">Subscribing to Locale Changes</mark>

Subscribe to locale changes to keep your application's translations in sync:

```tsx
import { useEffect } from 'react';
import { useAppClient } from '@akinon/app-client';
import { i18n } from '@akinon/akilocale/react';

const App = () => {
  const { locale, onLocaleChange } = useAppClient();

  useEffect(() => {
    // Set initial locale
    i18n.changeLanguage(locale);

    // Subscribe to locale changes from shell
    const unsubscribe = onLocaleChange((newLocale) => {
      i18n.changeLanguage(newLocale);
    });

    // Cleanup on unmount
    return unsubscribe;
  }, [locale, onLocaleChange]);

  return <AppContent />;
};
```

### <mark style="color:red;">Complete Setup Example</mark>

Here's a complete example of setting up i18n in a client application:

```tsx
import { useEffect } from 'react';
import { AppClientProvider, useAppClient } from '@akinon/app-client';
import { i18n, useTranslation } from '@akinon/akilocale/react';

// Initialize i18n (optional custom config)
// i18n.init({ backend: { loadPath: '/locales/{{lng}}/{{ns}}.json' } });

// Locale sync component
const LocaleSync = ({ children }: { children: React.ReactNode }) => {
  const { locale, onLocaleChange } = useAppClient();

  useEffect(() => {
    i18n.changeLanguage(locale);

    const unsubscribe = onLocaleChange((newLocale) => {
      i18n.changeLanguage(newLocale);
    });

    return unsubscribe;
  }, [locale, onLocaleChange]);

  return <>{children}</>;
};

// Your component using translations
const Dashboard = () => {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t('dashboard.title')}</h1>
      <p>{t('dashboard.welcome')}</p>
    </div>
  );
};

// Main app
const App = () => (
  <AppClientProvider config={{ isDev: true }}>
    <LocaleSync>
      <Dashboard />
    </LocaleSync>
  </AppClientProvider>
);
```

### <mark style="color:red;">Using with React-i18next Directly</mark>

If you prefer to use react-i18next directly instead of @akinon/akilocale:

```tsx
import { useEffect } from 'react';
import { useAppClient } from '@akinon/app-client';
import { useTranslation } from 'react-i18next';

const LocaleSync = ({ children }: { children: React.ReactNode }) => {
  const { locale, onLocaleChange } = useAppClient();
  const { i18n } = useTranslation();

  useEffect(() => {
    i18n.changeLanguage(locale);

    const unsubscribe = onLocaleChange((newLocale) => {
      i18n.changeLanguage(newLocale);
    });

    return unsubscribe;
  }, [locale, onLocaleChange, i18n]);

  return <>{children}</>;
};
```

### <mark style="color:red;">Best Practices</mark>

#### 1. Initialize Early

Set up locale management early in your application lifecycle, preferably at the top level:

```tsx
const App = () => (
  <AppClientProvider config={config}>
    <LocaleSync>
      <Router>
        <Routes />
      </Router>
    </LocaleSync>
  </AppClientProvider>
);
```

#### 2. Always Unsubscribe

Return the unsubscribe function to prevent memory leaks:

```tsx
useEffect(() => {
  const unsubscribe = onLocaleChange((newLocale) => {
    i18n.changeLanguage(newLocale);
  });

  return unsubscribe; // Important!
}, [onLocaleChange]);
```

#### 3. Handle Fallback Locale

Always have a fallback locale in case the received locale is not supported:

```tsx
const SUPPORTED_LOCALES = ['en', 'tr', 'de'];

const handleLocaleChange = (newLocale: string) => {
  const locale = SUPPORTED_LOCALES.includes(newLocale) 
    ? newLocale 
    : 'en';
  i18n.changeLanguage(locale);
};
```

#### 4. Lazy Load Translations

Consider lazy loading translations based on the current locale:

```tsx
const loadTranslations = async (locale: string) => {
  const translations = await import(`./locales/${locale}.json`);
  i18n.addResourceBundle(locale, 'translation', translations.default);
  i18n.changeLanguage(locale);
};
```

#### 5. Minimize Re-renders

Handle locale changes at a high level to minimize re-renders:

```tsx
// ✅ Good - Single locale sync at top level
const App = () => (
  <LocaleSync>
    <ManyChildComponents />
  </LocaleSync>
);

// ❌ Bad - Multiple components subscribing
const ChildComponent = () => {
  const { onLocaleChange } = useAppClient();
  // Each component subscribes separately
};
```

### <mark style="color:red;">Considerations</mark>

* The initial locale defaults to `'en'` if not provided by the shell
* Locale changes can occur at any time during user interaction
* Ensure your application gracefully handles locale changes during data loading

### <mark style="color:red;">Next Steps</mark>

* Hooks - Complete hooks reference
* Configuration - Application configuration
* API Reference - Complete API documentation


---

# 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://docs.akinon.com/akinon-ui/ui-protocol/client-application/i18n.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.
