Мультиязычность: next-intl для веб-приложений, i18next для Electron. Загружай ДО правки i18n/navigation.ts, proxy.ts с matcher локалей, messages/*.json и когда ссылка /en/... открывается на дефолтной локали, icon и opengraph-image отдаются без префикса локали, подсказки валидации формы остаются на английском, корневой not-found ломает hydration.
Installs into .claude/skills of the current project.
Are you the author of I18n Multilingual?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/kamiletar-i18n-multilingual)
---
name: i18n-multilingual
description: |
Мультиязычность: next-intl для веб-приложений, i18next для Electron. Загружай ДО правки i18n/navigation.ts, proxy.ts с matcher локалей, messages/*.json и когда ссылка /en/... открывается на дефолтной локали, icon и opengraph-image отдаются без префикса локали, подсказки валидации формы остаются на английском, корневой not-found ломает hydration.
---
# i18n Multilingual
Мультиязычность приложений: переводы, SEO, форматирование.
## ⚠️ Ловушки (разборы в доках)
- [nextjs-intl-plain-link-drops-locale-prefix](/.claude/docs/nextjs-intl-plain-link-drops-locale-prefix.md) — голый `next/link` на `/en/...` уводит на дефолтную локаль
- [nextjs-intl-matcher-metadata-routes](/.claude/docs/nextjs-intl-matcher-metadata-routes.md) — matcher не ловит `icon`/`opengraph-image`
- [letar-forms-missing-i18nprovider-english-hints](/.claude/docs/letar-forms-missing-i18nprovider-english-hints.md) — без `FormI18nProvider` подсказки валидации на английском
- [nextjs-root-notfound-no-root-layout](/.claude/docs/nextjs-root-notfound-no-root-layout.md) — корневой `not-found.tsx` без корневого layout
## ⚠️ Стеков ДВА, и это осознанное решение — не техдолг
Решение владельца от **2026-07-30** (принято при планировании локализации Animatrona и Animatrona
Player):
| Окружение | Стек |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
| **Веб-приложения** — лендинги, `driving-school` и остальные Next.js-приложения | **next-intl** (весь остальной этот скилл) |
| **Electron-стек** — `animatrona`, `animatrona-player`, `mobile-ui`, `main`-процессы, общие либы (`video-player-react`, `folder-player-react`, `web-player`) | **i18next** + `react-i18next` |
**Почему нельзя свести к одному:** `next-intl` завязан на Next.js — RSC, middleware, локаль в URL.
В shared-либе, в Vite-сборке и в Node-процессе `main` он не работает вообще, а переводы нужны сразу
во всех этих окружениях. При этом у веба есть SEO и локаль в URL, а у Electron нет ни того, ни
другого — то есть выигрыш next-intl там просто не применим.
⛔ **Не «унифицируй» стеки при рефакторинге.** Расхождение выглядит как недоделка, но попытка
перевести либы или main-процесс на `next-intl` их ломает. Если кажется, что это техдолг — это не он.
**Как применять в Electron-стеке:**
- общие либы несут свои `messages/{ru,en}.json` **внутри себя** и принимают опциональный override
`t` от приложения — чтобы либу можно было вставить в новое приложение без переписывания словаря;
- **не переводятся:** логи main-процесса, комментарии в коде (они по-русски по конвенции монорепо),
данные из внешних API (жанры/статусы/описания Shikimori — это данные, а не интерфейс).
Статус реализации и подробный план — `apps/animatrona/PLAN.md` §14 (i18next в зависимостях монорепо
на момент записи ещё нет — стек выбран, установка идёт вместе с этой фазой).
## next-intl (веб-приложения)
Дальше в этом скилле — только про веб-стек.
## Когда использовать
- Добавление поддержки нескольких языков
- Создание переводов для UI
- SEO оптимизация для локалей
- Форматирование дат, чисел, валют
## Быстрый старт
```typescript
// i18n.config.ts
export const locales = ['ru', 'en'] as const
export const defaultLocale = 'ru' as const
export type Locale = (typeof locales)[number]
```
## Переводы
```typescript
// messages/ru.json
{
"common": {
"hello": "Привет",
"welcome": "Добро пожаловать, {name}!"
},
"products": {
"title": "Каталог товаров",
"addToCart": "В корзину"
}
}
```
## Использование
```tsx
import { useTranslations } from 'next-intl'
export function Header() {
const t = useTranslations('common')
return <h1>{t('hello')}</h1>
} // С параметрами
<p>{t('welcome', { name: 'Иван' })}</p>
```
## Критичные правила
- **MUST** использовать `useTranslations` для клиентских компонентов
- **MUST** использовать `getTranslations` для серверных компонентов
- **SHOULD** структурировать переводы по доменам (common, products, etc)
- **NEVER** хардкодить текст напрямую в компонентах
## Reference файлы
- `reference/next-intl-setup.md` — настройка next-intl
- `reference/translations.md` — структура переводов
- `reference/seo-multilingual.md` — SEO для локалей
- `reference/date-number-formatting.md` — форматирование
- `reference/rtl-support.md` — поддержка RTL языков