Модуль Node.js для Next.js с локализацией и управлением состоянием Zustand.
- ✅ Простая локализация для React/Next.js приложений
- ✅ Управление переводами с помощью Zustand
- ✅ Поддержка вложенных ключей перевода
- ✅ Замена аргументов в строках перевода
- ✅ Хуки
useLocaleиuseTranslations - ✅ Компонент
TranslateProviderдля инициализации
$ npm install @makstashkevich/translate
# или
$ yarn add @makstashkevich/translateДля использования плагина оберните ваше приложение в TranslateProvider и передайте ему defaultLocale (язык по умолчанию) и translations (объект с переводами).
// app/layout.tsx или pages/_app.tsx
import { TranslateProvider } from '@makstashkevich/translate'
// Ваши переводы
const translations = {
en: {
common: {
hello: 'Hello, {name}!',
welcome: 'Welcome!'
}
},
ru: {
common: {
hello: 'Привет, {name}!',
welcome: 'Добро пожаловать!'
}
}
}
// Или импортируйте переводы из JSON-файлов:
// import enLocale from '@/locales/en.json';
// import ruLocale from '@/locales/ru.json';
// const translations = {
// en: enLocale,
// ru: ruLocale,
// };
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<TranslateProvider defaultLocale="en" translations={translations}>
{children}
</TranslateProvider>
</body>
</html>
)
}Используйте хук useLocale для получения текущего языка и функции setLocale для его изменения.
import { useLocale, setLocale } from '@makstashkevich/translate'
const LanguageSwitcher = () => {
const locale = useLocale()
const handleChangeLanguage = newLocale => {
setLocale(newLocale)
}
return (
<div>
Текущий язык: {locale}
<button onClick={() => handleChangeLanguage('en')}>English</button>
<button onClick={() => handleChangeLanguage('ru')}>Русский</button>
</div>
)
}Используйте функцию translate (или ее псевдоним t) для получения переведенных строк. Поддерживаются вложенные ключи и замена аргументов.
import { translate, t } from '@makstashkevich/translate'
const MyComponent = () => {
const userName = 'Мир'
return (
<div>
<p>{translate('common.hello', { name: userName })}</p>
<p>{t('common.welcome')}</p>
</div>
)
}Используйте хук useTranslations для получения всех загруженных переводов.
import { useTranslations } from '@makstashkevich/translate'
const DebugTranslations = () => {
const allTranslations = useTranslations()
return <pre>{JSON.stringify(allTranslations, null, 2)}</pre>
}children:React.ReactNode- Дочерние элементы, которые будут иметь доступ к контексту локализации.defaultLocale:LocaleType- Язык по умолчанию для приложения.translations:AllTranslations- Объект, содержащий переводы для всех поддерживаемых языков.
setLocale(locale: LocaleType): Устанавливает текущий язык.getLocale(): LocaleType: Возвращает текущий язык.setDefaultLocale(defaultLocale: LocaleType): Устанавливает язык по умолчанию.getDefaultLocale(): LocaleType: Возвращает язык по умолчанию.setTranslations(translations: AllTranslations): Устанавливает все переводы.translate(key: string, args?: Args): string: Возвращает переведенную строку по ключу, с возможностью замены аргументов. Псевдоним:t.useLocale(): LocaleType: Хук для получения текущего языка.useTranslations(): AllTranslations: Хук для получения всех загруженных переводов.
LocaleType = 'ru' | 'en' | string: Тип для обозначения языка.Translations = Record<string, any>: Объект переводов для конкретного языка.AllTranslations = Record<LocaleType, Translations>: Объект, содержащий переводы для всех языков.Args = Record<string, string | number> | (string | number)[]: Тип для аргументов, используемых в строках перевода.
Библиотека использует Zustand для управления состоянием локализации. TranslateProvider инициализирует это состояние, а хуки и функции предоставляют удобный интерфейс для взаимодействия с ним. Переводы хранятся в глобальном хранилище Zustand, что обеспечивает их доступность в любом месте приложения без необходимости пробрасывать пропсы.
Почему я получаю ошибку несоответствия сервера/клиента (hydration mismatch)?
Поскольку состояние локализации управляется на стороне клиента с помощью Zustand, при использовании хуков useLocale или useTranslations на сервере (SSR/SSG) вы можете столкнуться с ошибками несоответствия гидратации. Чтобы избежать этого, убедитесь, что компоненты, использующие эти хуки, рендерятся только на клиенте, например, с помощью useEffect или next/dynamic с ssr: false.
import { useState, useEffect } from 'react'
import { useLocale } from '@makstashkevich/translate'
const ClientSideComponent = () => {
const [mounted, setMounted] = useState(false)
const locale = useLocale()
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) {
return null
}
return <p>Текущий язык на клиенте: {locale}</p>
}Могу ли я использовать этот пакет с Gatsby или CRA?
Да, поскольку это стандартный React-компонент и хуки, его можно использовать в любом React-приложении, включая Gatsby и Create React App.
Как добавить новые языки?
Просто добавьте новые языки в объект translations, который вы передаете в TranslateProvider. Тип LocaleType поддерживает string, поэтому вы можете использовать любой строковый идентификатор для вашего языка.
const translations = {
en: {
/* ... */
},
ru: {
/* ... */
},
fr: {
/* ... */
} // Новый язык
}
;<TranslateProvider defaultLocale="en" translations={translations}>
{children}
</TranslateProvider>Важное примечание для пользователей Next.js: React Compiler
Ни в коем случае не включайте reactCompiler в вашем файле next.config.js (или next.config.ts), если вы используете эту библиотеку. Включение reactCompiler может помешать динамическому обновлению переводов на странице, что приведет к некорректному поведению локализации.
Пример некорректной конфигурации:
// examples/example/next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
reactCompiler: false // Эту строку НЕЛЬЗЯ устанавливать в true
}
export default nextConfigУбедитесь, что reactCompiler либо отсутствует, либо явно установлен в false в вашем конфигурационном файле Next.js.