# Next.js i18n: App Router + next-intl Tutorial

## Метаданные

- **Канал:** Frontend Basics
- **YouTube:** https://www.youtube.com/watch?v=h3IA_Iax-dk
- **Источник:** https://ekstraktznaniy.ru/video/38320

## Транскрипт

### Segment 1 (00:00 - 05:00) []

Привет! В этом видео я покажу вам, как реализовать интернализацию в Next. js. Мы рассмотрим, как динамически переключать языки, переводить страницы и даже обновлять заголовки страниц в зависимости от выбранного языка. Кроме того, я покажу, как настроить сборку Next. js для статического экспорта этих страниц. Часть первая: Начальная настройка. Начнём с добавления Next. js в библиотеку. С помощью этой библиотеки мы сможем обрабатывать интернализацию во внешнем интерфейсе. После установки мы создадим Next. js. В файле конфигурации MGS мы обернем наш следующий конфигурационный файл с помощью create next in plugin. Я рекомендую добавить аннотацию типа в ваш следующий конфигурационный файл для проверки типов. Мы создадим папку messages. Эта папка будет содержать наши переводы для каждого языка. Для этой демонстрации я буду использовать английский и немецкий языки. Пока что мы можем оставить эти файлы пустыми. Далее мы создадим файл конфигурации TTS. Этот файл будет содержать наши локализации. Мы создадим IAT и... Файл TS находится в папке source. Расположение файла важно, если вы хотите создать его как ASWH. Вам потребуется дополнительная конфигурация внутри файла i8n. Мы импортируем наши локальные переменные и экспортируем их для получения функции конфигурации. Эта функция будет делать две вещи: если локальная переменная неизвестна, она вернет страницу "Не найдено"; если локальная переменная известна, она вернет JSON. Мы будем использовать параметр local для динамического импорта правильного языка для перенаправлений и запоминания текущего языка. Нам нужен промежуточный обработчик (middleware). Этот файл также должен находиться в папке source. Если у вас уже есть промежуточный обработчик и некоторая логика внутри него, вам потребуется дополнительная настройка. В противном случае вы можете использовать функцию создания промежуточного обработчика, предоставляемую библиотекой. Мы передадим наши локальные переменные в промежуточный обработчик и установим локальную переменную по умолчанию. В случае неизвестной локальной переменной она указывается вместе с параметром mature. Мы указываем, на каких панелях будет вызываться промежуточный обработчик. Поскольку у нас есть английский и немецкий языки, мы будем вызывать этот промежуточный обработчик, если компонент начинается с этих языков или если компонент является корневым. После этих настроек нам нужно создать папку local и переместить туда все содержимое. Эта папка local будет определять язык и передавать его нашему компоненту. Если у вас нет файла макета, Вам следует создать его внутри. Мы будем получать доступ к локальному параметру, получать сообщения и передавать их в следующий клиентский провайдер. Этот провайдер предоставляет нам доступ ко всем переводам на клиентском сайте. Также мы передадим свойство языка в HTML Tech. Теперь мы можем перевести нашу главную страницу в английский перевод. Давайте создадим объект с тем же именем, что и компонент нашей главной страницы, и добавим заголовок. Я скопирую и вставлю его из компонента. Внутри компонентов используйте хук used translations для доступа к переводам. Вам нужно передать ключ, к которому вы хотите получить доступ. В этом примере ключом будет index page. Чтобы перевод работал, нам нужно передать ключ в функцию T. Здесь мы передадим заголовок. Давайте запустим наш сервер и проверим, правильны ли эти конфигурации. Кажется, что мы импортируем стиль. CSS находится в файле макета, но он его не находит. Ах, мы переместили файл макета на один уровень ниже, поэтому файл не смог найти стили. CSS, хорошо, теперь приложение работает, и мы видим именно то, что ожидали. Если вы посмотрите на адресную строку, префикс N добавляется автоматически. Это значит, что наш промежуточный обработчик работает. Когда я меняю n на D, заголовок ломается в режиме разработки. Если в языке отсутствует ключ, мы видим это так. Когда мы добавляем перевод в немецкий JSON, все возвращается в норму. Также благодаря нашему промежуточному ПО, даже если я хочу перейти к питомцу без языкового префикса, он перенаправляет меня к нужному питомцу, поэтому он запоминает последний предпочтительный язык. Часть вторая: форматирование. У нас здесь абзац с фрагментом, который нужно отформатировать. Если вы посмотрите на компонент, то увидите, что код используется внутри абзаца. Давайте скопируем текст и посмотрим, как мы можем это обработать. Как и раньше, мы можем использовать функцию T и передать описание в качестве аргумента. Однако, когда мы это делаем, этот перевод не отображается на странице. Если вы посмотрите в терминале, вы увидите сообщение об ошибке форматирования. Это потому, что наш перевод включает HTML-тег. Если ваш перевод включает HTML-тег, вы не можете использовать функцию T напрямую, вы должны использовать t. Функция reach прямо сейчас, как мы уже говорили, всякий раз, когда вы видите тег кода внутри перевода, отображает элемент кода с помощью t. Функция `request` отображает перевод на странице. Эта функция действительно мощная, поскольку мы можем делать с этим элементом все, что угодно, например, добавлять пару классов. Кроме того, вам не нужно указывать HTML-код, вы можете назвать его как угодно. Если вы назовете его ` example component` вот так, то внутри вызова функции вы сможете получить к нему доступ как к ` example component`. Таким образом, мы, по сути, связываем тег, который мы поместили внутрь ` translation`, с элементом, который мы хотим отобразить. Часть третья: навигация. Когда мы хотим перейти на другую страницу в нашем приложении, мы видим эту ошибку. Это происходит потому, что с этого момента нам всегда нужен языковой префикс. Я подключаю префикс к ссылке навигации вот так, и, кажется, это работает. Однако жесткое кодирование языкового префикса таким образом не идеально, поскольку пользователь может находиться в другом месте. Далее библиотека Intel предоставляет удобный способ решения этой проблемы в нашем файле конфигурации. Давайте создадим пару переменных, которые нам нужно присвоить имена пользователям нашего приложения, и мы сообщим библиотеке, что нам всегда нужен локальный префикс. Создайте новый файл с именем `navigation` и импортируйте эту длинную функцию. Импортируйте наши конфигурации из файла конфигурации и передайте их в функцию. По сути, эта функция оборачивает Маршрутизация NEXJ, хуки и компоненты. С этого момента мы должны использовать эти интересные функции, а

### Segment 2 (05:00 - 10:00) [5:00]

не версии NEXJS. Поэтому давайте перейдем к компоненту навигационной ссылки и заменим компонент ссылки NEXJS нашим оберткой. Теперь, когда мы переходим к другому питомцу, локальный префикс включается. Когда я меняю локальный префикс питомца, он также меняется. Часть четвертая. О, я новый разработчик в этом проекте, позвольте мне добавить сюда компонент ссылки. Почему здесь два компонента ссылки? Как XGS Pro, я знаю, что мне нужно импортировать компонент ссылки NEXJS. Нет проблем, верно? Ой. Когда к проекту присоединяется новый разработчик или когда вы возвращаетесь к нему через некоторое время, может быть трудно помнить о необходимости всегда импортировать из папки навигации. Чтобы предотвратить это, мы можем добавить ошибку SINT под названием « Нет ограниченного импорта». Эта ошибка будет возникать, когда мы захотим импортировать либо компонент ссылки, либо хуки, связанные с навигацией. Когда я пытаюсь импортировать ссылку NEXJS, она выдает ошибку, и этап сборки завершается с ошибкой. Когда вы заменяете ссылку обертками, ошибка SINT исчезает. Часть пятая. Переключатель локали. Я хочу изменить язык как пользователь, но мы Здесь нет элемента select, давайте сначала его создадим. Создайте компонент под названием local switcher select. Поскольку у этой функции будет обработчик onclick, мы пометим его как клиентский компонент. Он будет принимать в качестве свойств значения по умолчанию для дочерних элементов и метку. Мы не хотим блокировать пользователя при обновлении страницы, поэтому мы будем использовать хук use transition в функции on select change. Мы получим следующего пользователя из определенной локации один раз и начнем наш переход. Мы хотим сохранить имя питомца и параметры неизменными и изменить только локацию, поскольку имя питомца и параметры всегда совпадают для текущих маршрутов, мы можем пропустить проверки во время выполнения. Компонент будет иметь пару классов tent, но по сути это компонент select. Хорошо, теперь пора создать компонент local switcher. Причина, по которой мы разделили компоненты, заключается в том, что мы хотим, чтобы этот компонент был серверным компонентом. Давайте создадим переводы для этого компонента. Для немецкого языка отсутствует описание перехода, поэтому я его заполняю. Мы будем использовать хук use local, чтобы получить локацию, даже несмотря на то, что этот компонент является серверным компонентом. Мы можем вызвать этот хук. Такой подход позволяет нам создавать общие компоненты, которые работают как в качестве клиентских, так и серверных компонентов. Импортируйте компонент выбора переключателя local и вставьте необходимые свойства. Мы еще не создали перевод метки, поэтому давайте сделаем это. Мы сопоставим каждый доступный локальный параметр, но вот в чем дело: для каждого локального параметра мы используем один и тот же ключ перевода. Как это будет работать в ваших файлах перевода? Вы можете добавить немного логики. Если вы добавите фигурные скобки, это означает, что произойдет некоторая логика. Сначала я ввожу local, чтобы указать, что это значение определит окончательный перевод, затем я пишу аргумент select. В библиотеке есть несколько подобных аргументов. С аргументом select я сначала укажу ключ, затем значение. Первый ключ — D, а значение — немецкий язык. Второй ключ — n, а значение — английский язык. Если наш локальный параметр не D и не n, окончательное значение будет неизвестно. Таким образом, если значение D, верните это, если значение n, верните это, а если нет, верните это. Давайте я скопирую и вставлю немецкий перевод, как в t. В функции `reach` мы передаем текущую локаль, и если вы измените ключ локальной переменной, вам также нужно будет обновить перевод. Теперь компонент готов, мы можем добавить его в нашу панель навигации. Отлично, я могу изменить язык, и при обновлении страницы он запоминает предыдущую локаль. Часть шестая: статическое отображение и метаданные страницы. Хорошо, я заполнил недостающие переводы для проекта. Теперь все, что вы видите на странице, поступает из наших файлов переводов. Ура! У нас есть классный сайт с поддержкой интернационализации. Но подождите, посмотрите на наш заголовок. Я имею в виду, хотя бы покажите английский заголовок. Это не единственная наша проблема. Когда я собирал приложение, мы увидели, что наши локальные переменные динамические. Nextjs говорит, что я не знаю возможных локалей, поэтому мне нужно создавать их по ходу работы. Мы должны исправить эти две проблемы для лучшего пользовательского опыта. Чтобы создавать страницы статически, перейдите к компоненту макета и экспортируйте функцию `generatestaticparams`. Внутри этой функции возвращайте ваши локали следующим образом: чтобы узнать возможные локали во время сборки, для обновления заголовка экспортируйте метод `generate` этой функции. Эта функция имеет доступ к нашей локальной переменной, поэтому мы будем получать переводы, используя метод `gate`. Функция переводов не знает, какой локаль вам нужен, поэтому нам нужно указать её и пространство имён внутри пространства имён локального макета. У нас есть заголовок на каждом языке. Если вы вернёте переведённый заголовок, проблема будет решена. Вам нужно вызвать функцию unstable set request local на каждой странице и макете, где вы планируете включить статическую отрисовку. С помощью этой функции серверные компоненты могут получить доступ к параметру local, даже если имя функции указывает на её нестабильность, на самом деле она надёжна. К сожалению, на данный момент другого способа сделать это нет, поэтому не забудьте добавить её на каждую страницу и макет после этих изменений. Когда я запускаю приложение, заголовок видеомагнитофона меняется в зависимости от языка, и если я создаю производственную сборку, мы видим, что статические страницы создаются для каждой доступной локали. Спасибо за просмотр этого видео. Если оно вам помогло, вы

### Segment 3 (10:00 - 10:00) [10:00]

можете подписаться на канал, чтобы получать больше уроков.
