Ближе к концу прошлого года (2018) я создал относительно простой интерфейс React для своей компании Wundershine. Раньше я создавал приложения NextJs, и раньше создавал локализованные приложения, но никогда не было локализованного приложения NextJs.

В целом, большая часть интернационализации в React осуществляется через react-intl, но если вы предпочитаете (как я) решение, более подходящее для i18next, есть react-i18next - реализация i18next, специфичная для React, поддерживаемая основной командой i18next. . Я должен добавить здесь предостережение, что локализовать SSR с помощьюreact-intl определенно возможно, и это определенно делается в корпоративных производственных средах (я работаю в одной из таких компаний).

Решив остаться в мире i18n, я начал играть с react-i18next в некоторых простых приложениях NextJs и быстро понял, что, хотя интернационализировать простое клиентское приложение React в наши дни довольно легко, интернационализировать приложение SSR React (даже с учетом того, как easy NextJs делает это) - довольно трудное предложение.

Я начал отправлять PR, чтобы помочь исправить пример react-i18next NextJs, и со временем команда i18next и я поняли, что имеет смысл просто создать новый пакет. Так родился next-i18next, и, насколько мне известно, это самый простой способ сделать локализованные приложения SSR, точка. Теперь это также есть в примерах репозиториев react-i18next и NextJs.

Итак, давайте сделаем пошаговое руководство.

Следующее предполагает предварительное знание NextJs.

Настройка

Для начала нам понадобится работающее приложение NextJs. Мы сделаем это, создав новый каталог с именем next-i18next-demo и несколько ключевых файлов: package.json и pages каталог с index.js внутри:

next-i18next-demo
├── package.json
└── pages
    └── index.js

Затем мы добавим все необходимые зависимости, выполнив следующие действия:

yarn add express next next-i18next react react-dom

А затем добавьте стандартные скрипты NextJs в наш package.json вот так:

Давайте обновим наш index.js файл, чтобы на самом деле экспортировать значимый компонент React:

Теперь, если мы запустим yarn dev, мы увидим:

Большой! У нас есть приложение NextJs. Давай переведем.

Процесс локализации

Первым шагом будет добавление нашего актуального локализованного контента. Этот пример очень простой, но на самом деле вы можете написать весь свой интерфейс на одной локали, а затем, когда вы приблизитесь к выпуску, переводчики будут выполнять большие объемы работы.

В качестве пакета next-i18next заимствует функциональность как у react-i18next, так и у NextJ. Одна из таких функций, которыми мы пользуемся, - это static каталог, предоставляемый NextJs, который автоматически становится общедоступным для нашего клиента через наш сервер Node. Мы можем просто вставить туда наш локализованный контент, и больше ничего делать не нужно - он уже доступен нашему Node-приложению через файловую систему и нашему клиенту через сетевой запрос к my-app.com/static/my-asset.txt.

По умолчанию next-i18next ожидает, что вы будете организовывать локализованный контент следующим образом:

next-i18next-demo
└── static
    └── locales
        ├── en
        |   └── common.json
        └── de
            └── common.json

В этом примере у нас будет пространство имен по умолчанию на английском языке и внешнее пространство имен на немецком языке, оба с одним ключом.

static/locales/en/common.json:

static/locales/de/common.json:

Теперь, когда наш контент для локализации готов, мы можем инициализировать наш класс next-i18next.

(В будущем мы могли бы переписать пакет более функционально, но пока он основан на классах.)

Давайте добавим i18n.js файл верхнего уровня в соответствии с next-i18next документами:

Этот файл будет использоваться как нашим процессом NextJs, так и настраиваемым сервером Node / Express, поэтому, если вы хотите использовать синтаксис ESM, вам нужно позаботиться о транспиляции самостоятельно.

Класс NextI18NextInstance предоставляет нам почти все необходимое для локализации нашего приложения. Нам просто нужно сделать еще две вещи:

  1. Создайте файл _app.js и оберните его appWithTranslation HOC, предоставленным нашим NextI18NextInstance - это то, что включает большую часть магии локализации SSR
  2. Создайте файл server.js и используйте nextI18NextMiddleware - это то, что определяет язык на основе заголовков, создает подпути локали и т. Д.

Вот наш _app.js:

А вот наш server.js:

Обратите внимание, что мы передаем NextI18NextInstance в nextI18NextMiddleware. За кулисами этот NextI18NextInstance предоставит клонированный экземпляр i18n для каждого req Express, который затем сериализуется и отправляется клиенту через существующий шаблон NextJs _40 _ / _ 41_.

Обратите внимание, что нам нужно будет изменить наши сценарии NextJs сейчас, поскольку точка входа нашего приложения изменилась на наш собственный server.js:

Вот и все! Были сделаны. Мы можем добавить актуальный локализованный контент через withNamespaces на нашу домашнюю страницу и добавить кнопку для изменения локали:

Теперь, если мы запустим наше приложение, мы увидим:

Заметьте, я включил опору namespacesRequired в свой getInitialProps - именно так мы выполняем «расщепление кода» пространства имен в next-i18next. Другими словами, мы отправляем клиенту только необходимые пространства имен (как определено в namespacesRequired). (Первоначальная идея заключалась в том, чтобы сделать обход дерева и сделать это автоматически, но оказалось, что в настоящее время нет отличного способа сделать это, не влияя на производительность.)

Подведение итогов

Итак, это все! Это простейший путь из ничего к локализованному приложению NextJs. Есть несколько других важных функций, поддерживаемых next-i18next, которые я здесь не обсуждал, например localeSubpaths, которые вы можете обнаружить самостоятельно.

Не стесняйтесь обращаться ко мне напрямую с любыми вопросами по next-i18next или предложениями по этой статье.