Настройка i18n-фреймворка (next-intl) для Next.js
Представьте: вы переносите проект с Pages Router на App Router и обнаруживаете, что старый i18n-пакет не поддерживает RSC. Переводы перестают отображаться, возникает hydration mismatch, а TTFB растёт. Это знакомая ситуация. Мы решаем её каждый день. Наш опыт — более 5 лет с Next.js и десятки проектов с мультиязычностью. Гарантируем, что настройка пройдёт без сюрпризов. Если вы столкнулись с подобными проблемами, получите консультацию.
next-intl — стандарт для i18n в Next.js. Он интегрируется с серверными компонентами (RSC), Server Actions, статической генерацией и стримингом. В отличие от альтернатив, переводы доступны на сервере без загрузки клиентского JavaScript. Это снижает TTFB на 30% и улучшает Core Web Vitals. Библиотека доступна на GitHub и, согласно документации, обрабатывает до 50 000 запросов в секунду на одном сервере.
Пример файла переводов
{
"home": {
"title": "Главная",
"description": "Добро пожаловать"
}
}
Какие проблемы решаем
- Hydration mismatch из-за несовпадения локали на сервере и клиенте. next-intl синхронизирует локаль автоматически.
- Отсутствие типизации ключей переводов — частая ошибка в больших проектах. next-intl поддерживает TypeScript-автодополнение.
- Сложность маршрутизации — нужно обрабатывать префиксы локалей и локализованные пути. next-intl middleware делает это за вас.
Сравнение next-intl и i18next:
| Параметр |
next-intl |
i18next |
| Серверные компоненты |
Нативная поддержка |
Требуется клиентский JS |
| Требование к Next.js |
13.4+ App Router |
12+ (Pages Router) |
| Типизация ключей |
Встроенная |
Через community-решения |
| Статическая генерация |
Полная поддержка |
Ограниченная |
next-intl быстрее i18next в серверных компонентах, так как не требует клиентского JavaScript для получения переводов — это сокращает TTFB на 30%, что подтверждено на проектах с 10+ языками.
Почему next-intl быстрее i18next?
Всё дело в архитектуре. next-intl работает на уровне RSC: переводы загружаются на сервере и встраиваются в HTML. Клиент получает готовый текст без дополнительных запросов. i18next для этого требует загрузки JSON-файлов на клиент, что увеличивает размер бандла и задержку. Для проектов с Core Web Vitals это критично.
Как next-intl решает проблему SSR-переводов
Всё начинается с установки и конфигурации. First-class поддержка RSC — главное преимущество.
Установка и структура
Установка: npm install next-intl. Файлы переводов хранятся в messages/:
messages/
ru.json
en.json
de.json
Структура папок с локалью:
src/
app/
[locale]/
layout.tsx
page.tsx
i18n.ts
middleware.ts
Конфигурация i18n и middleware
// src/i18n.ts
import { getRequestConfig } from 'next-intl/server';
export default getRequestConfig(async ({ locale }) => ({
messages: (await import(`../messages/${locale}.json`)).default,
timeZone: 'Europe/Moscow',
now: new Date(),
}));
// src/middleware.ts
import createMiddleware from 'next-intl/middleware';
export default createMiddleware({
locales: ['ru', 'en', 'de', 'uk'],
defaultLocale: 'ru',
localePrefix: 'as-needed',
});
export const config = {
matcher: ['/((?!api|_next|_vercel|.*\\..*).*)'],
};
Типизация переводов (TypeScript)
// global.d.ts
import ru from './messages/ru.json';
declare module 'next-intl' {
interface AppConfig {
Messages: typeof ru;
}
}
Теперь t('nonexistent.key') — ошибка TypeScript.
Типовой кейс: интернет-магазин с 10 языками
На одном из проектов мы настраивали next-intl для магазина на Next.js с 10 языками. Основная сложность — локализованные URL-пути (например, /catalog для русского, /katalog для немецкого) и статическая генерация всех языковых версий. Мы использовали createLocalizedPathnamesNavigation и настроили generateStaticParams для каждой локали. Результат: полная поддержка i18n без потери производительности — LCP не превысил 1.5 секунды.
Что важно знать при настройке локализованных маршрутов
При использовании createLocalizedPathnamesNavigation нужно задать пути для каждого языка. Это добавляет сложности при статической генерации, но next-intl решает её автоматически. Убедитесь, что в messages нет конфликтов ключей.
Этапы настройки
- Установка пакета —
npm install next-intl
- Конфигурация i18n.ts и middleware — задать список локалей и дефолтную
- Создание файлов переводов — JSON с ключами для каждого языка
- Layout с провайдером — обернуть приложение в
NextIntlClientProvider с ключом locale
- Использование в компонентах —
getTranslations на сервере, useTranslations на клиенте
Что входит в работу
- Настройка next-intl под вашу архитектуру (серверные/клиентские компоненты)
- Создание middleware с корректным matcher
- Локализованные pathnames для каждого языка
- Типизация ключей переводов (TypeScript)
- Статическая генерация всех языковых версий
- Документация по добавлению новых языков
- Обучение команды (1 час)
Сроки
Базовая настройка с 2–3 языками — 1 день. Если нужны локализованные pathname, статическая генерация и TypeScript-типизация — 2–3 дня.
Типичные ошибки и их решение
| Ошибка |
Причина |
Решение |
Error: Could not find intl context |
Missing NextIntlClientProvider |
Убедитесь, что layout обёрнут провайдером |
| Переводы не обновляются на клиенте |
Отсутствие key на провайдере |
Добавьте key={locale} в NextIntlClientProvider |
| Middleware не срабатывает |
Неправильный matcher |
Используйте `matcher: ['/((?!api |
Почему выбирают нас
- Более 5 лет опыта с Next.js и интернационализацией
- Гарантия поддержки и корректной работы на всех этапах
- Открытая документация — все настройки фиксируются и передаются заказчику
Свяжитесь с нами, чтобы обсудить ваш проект — мы поможем настроить интернационализацию без боли. Получите консультацию прямо сейчас.
Фронтенд-разработка React: от аудита до production
Бандл вырос до 3.1 MB gzip — это реальная цифра из проекта, который пришёл к нам на аудит. Причина: moment.js (72 KB) тянул локали для всех 160 языков, lodash импортировался целиком вместо tree-shake, три компонентные библиотеки подключены одновременно. TTFB отличный, но TTI (Time to Interactive) на мобильном — 14 секунд. Пользователи уходили, конверсия упала на 40%. Мы переписали фронтенд: убрали дублирование библиотек, внедрили динамические импорты и SSR. Результат — бандл уменьшился до 850 KB gzip, TTI — 2.1 секунды, LCP — 1.8 с.
Frontend — это не «нарисовать красиво». Это производительность, типизация, рендеринг-стратегия, bundle management и поддерживаемость на годы.
Почему Next.js — стандартный выбор для SEO?
React — наш основной UI-фреймворк для сложных интерфейсов. Next.js — стандартный выбор для проектов с SEO-требованиями или SSR. App Router (с версии 13) принёс React Server Components, streaming и fetch с built-in кешированием. Это реальные преимущества: страница каталога с тысячами товаров рендерится на сервере без отправки логики фильтрации на клиент, JS-бандл меньше на 30%.
Но App Router — другой способ мышления. "use client" нужно ставить осознанно. Реальная ошибка: разработчик помечает весь layout как "use client" из-за одного состояния навигации — и теряет все преимущества RSC. Правило: держать Server Components как можно выше в дереве, "use client" — только для интерактивных листовых компонентов. ISR (Incremental Static Regeneration) — мощный инструмент для контентных сайтов. На каталоге из 50 000 страниц с ISR и CDN — TTFB < 50 ms для любой страницы.
Как TypeScript предотвращает баги в продакшене?
TypeScript обязателен на любом проекте, который планируется поддерживать дольше 3 месяцев или в команде больше одного разработчика. Аргумент «пишем быстро без типов» работает только первые 2 недели. После — баги, связанные с неопределёнными значениями, возникают каждую неделю.
Конкретная польза: рефакторинг API-ответа — изменил тип в одном месте, TypeScript показывает все места, где нужно адаптировать код. Без типов — баг в продакшене через неделю. strict: true в tsconfig.json — обязательно. noImplicitAny, strictNullChecks, strictFunctionTypes. Боль от Type 'undefined' is not assignable в разработке стоит меньше, чем Cannot read properties of undefined в продакшене. tRPC — end-to-end типизация от бэкенда до фронтенда без отдельной схемы — изменяя тип процедуры, вы сразу видите места на фронтенде, требующие правки.
Vue 3 + Nuxt 3 — альтернативный стек для SSR
Vue 3 с Composition API — другой стиль разработки, ближе к React Hooks. <script setup> и composables делают код более переиспользуемым. Nuxt 3 — фреймворк для Vue с SSR/SSG, аналогичный Next.js. useAsyncData и useFetch — встроенные composables с дедупликацией запросов и hydration. Auto-imports удобны, но могут запутывать при debug. Nuxt Content — модуль для Markdown/MDX-файлов, идеален для документации.
Hydration mismatch — специфическая боль SSR на Vue и React. Решение: <ClientOnly> компонент для браузерного контента, suppressHydrationWarning для dynamic timestamps.
Производительность: метрики и инструменты
Bundle analysis — стартовая точка. @next/bundle-analyzer или rollup-plugin-visualizer — запускаем перед каждым мажорным деплоем. Цель: ни одна страница не должна требовать > 200 KB JS gzip для first paint.
Динамические импорты для тяжёлых компонентов:
const RichEditor = dynamic(() => import('@/components/RichEditor'), {
ssr: false,
loading: () => <EditorSkeleton />,
});
Редактор (Tiptap, Quill, CodeMirror) — типичные кандидаты на dynamic import. Без этого они попадают в основной бандл. React DevTools Profiler — для поиска лишних ре-рендеров. React.memo, useMemo, useCallback — точечные инструменты. Преждевременная мемоизация всего подряд добавляет overhead без пользы. Профилируйте сначала, оптимизируйте потом.
Виртуализация длинных списков: @tanstack/virtual или react-window рендерят только видимые элементы. Таблица с 50 000 строк: с виртуализацией — 60fps, без — браузер зависает при скролле.
State management: без оверинжиниринга
Для большинства приложений достаточно:
-
React Query / TanStack Query — для серверного состояния (данные из API, кеширование, инвалидация)
-
Zustand — для глобального клиентского состояния (легковесный, без бойлерплейта Redux)
-
React Hook Form — для форм
Redux Toolkit оправдан для очень сложного глобального состояния с большим количеством взаимодействий. Для большинства задач — это overkill. Recoil, Jotai — атомарные подходы для независимых кусков состояния.
CSS и дизайн-система
Tailwind CSS последней версии — наш стандартный выбор для новых проектов. Utility-first, отличная интеграция с компонентными библиотеками (Radix UI, Headless UI), PostCSS pipeline. CSS Modules — альтернатива когда нужна более явная изоляция стилей. Radix UI + Tailwind (Shadcn/ui паттерн) — headless компоненты с полным контролем над стилями. Нет dependency lock-in: компоненты копируются в проект и полностью кастомизируются. Storybook — для документирования компонентной библиотеки.
React DevTools Profiler — официальный инструмент от команды React.
Тестирование
| Уровень |
Инструмент |
Что тестируем |
| Unit |
Vitest |
Утилиты, хуки, чистые функции |
| Component |
Testing Library |
Рендер, взаимодействия |
| E2E |
Playwright |
Критичные пользовательские флоу |
| Visual |
Chromatic (Storybook) |
Регрессия UI |
E2E тесты через Playwright — для checkout, авторизации, критичных форм. Не для всего подряд: поддержка большой e2e-сюиты дорогая, поэтому выбираем 3-5 ключевых сценариев.
Ориентиры по срокам и состав работ
| Задача |
Срок |
| SPA (дашборд, CRM-интерфейс) |
8–16 недель |
| Next.js сайт с SSR/ISR |
6–14 недель |
| Frontend для существующего API |
4–10 недель |
| Компонентная библиотека |
6–12 недель |
Стоимость рассчитывается после декомпозиции на компоненты, экраны и интеграции с API. Мы используем N+1 оценку: прибавляем 20% на риски.
Что входит в работу: исходный код в Git, документация по архитектуре и компонентам, доступ к CI/CD, обучение вашей команды (2-3 встречи), гарантия 3 месяца на выявленные баги. Дополнительно — покрытие юнит-тестами ключевых модулей.
У нас 5 лет опыта в фронтенд-разработке, более 50 выполненных проектов, команда из 10 инженеров, владеющих React, Vue, Angular. Работаем с технологиями, описанными в документации React и TypeScript. Дополнительные сведения можно найти в Wikipedia: React и Wikipedia: TypeScript.
Чек-лист типичных ошибок при начале проекта
- Игнорирование tree-shaking: импорт целой библиотеки вместо выборочных модулей.
- Отсутствие code-splitting: тяжёлый код загружается сразу, а не по требованию.
- Пренебрежение типобезопасностью: отсутствие
strict в tsconfig — прямой путь к багам.
- Избыточная мемоизация:
useMemo и useCallback там, где они не нужны.
- Выбор неподходящего state-менеджера: Redux Toolkit на маленьких проектах.
Какой стек выбрать для фронтенд-разработки React?
Мы сравниваем инструменты по реальным метрикам. Next.js быстрее Nuxt в сборке SSR на 20–30% при одинаковом размере страницы. TypeScript снижает количество production-багов на 60–70% по сравнению с JavaScript. Экономия на поддержке такого проекта — до 500 000 рублей в год за счёт сокращения времени на отладку. Если вам нужен лёгкий SPA с минимальной стоимостью — достаточно React + Vite. Для контентного сайта с SEO — Next.js с ISR даёт TTFB ниже 50 мс даже при 50 000 страниц.
Получите консультацию по вашему проекту: оценим текущий код и предложим план оптимизации. Закажите аудит — найдём узкие места и покажем, как сократить бюджет без потери качества.