Спросите свой вопрос и получите сводку документа, используя эту страницу и выбранного вами поставщика AI
История версий
- "Использование middleware и хуков remix-intlayer"v9.5.519.09.2026
- "Начальная документация для Remix 3"v9.5.009.09.2026
Содержимое этой страницы было переведено с помощью ИИ.
Смотреть последнюю версию оригинального контента на английскомЕсли у вас есть идея по улучшению этой документации, не стесняйтесь внести свой вклад, подав запрос на вытягивание на GitHub.
Ссылка на документацию GitHubКопировать Markdown документа в буфер обмена
Перевод вашего сайта Remix 3 с помощью Intlayer
В этом руководстве показано, как интегрировать Intlayer для удобной интернационализации в приложениях Remix 3 с маршрутизацией с учетом языка, типобезопасными объявлениями контента, серверными JSX-компонентами и поддержкой сред выполнения Node.js, Bun, Deno и Cloudflare Workers.
Что такое Remix 3?
Remix 3 представляет собой фундаментальный архитектурный сдвиг в сторону модульного, независимого от среды выполнения веб-фреймворка, полностью построенного на веб-стандартах. Вместо привязки к конкретным сборщикам или проприетарным серверным API, Remix 3 распространяется в виде специализированных модульных пакетов:
remix/fetch-router(илиremix/router): Легковесная, совместимая со стандартами маршрутизация на базе Fetch API (RequestиResponse).remix/ui: Модель JSX-компонентов (jsxImportSource: "remix/ui"). Компонент представляет собой setup-функцию, возвращающую функцию рендеринга. Это похоже на React, но состояние сохраняется в обычных JavaScript-замыканиях.remix/middleware/render: Устанавливаетcontext.render(<Page />)для каждого запроса, передавая дерево JSX в потоковый HTML-ответResponse.remix/node-fetch-server: Серверные адаптеры для Node.js с нативной поддержкой Bun, Deno и edge-сред.remix/cookie: Криптографически безопасный парсинг и сериализация файлов cookie.
В сочетании с Intlayer и пакетом remix-intlayer, middleware локали плюс те же хуки useIntlayer / useDictionary / useLocale, что и в react-intlayer, привязанные к контексту запроса Remix, вы получаете полноценную систему интернационализации, обеспечивающую безопасность типов во время компиляции, автоматические переводы с помощью ИИ, серверный рендеринг без накладных расходов и бесшовную маршрутизацию по локалям.
Содержание
Почему стоит выбрать Intlayer?
По сравнению с традиционными решениями, такими как i18next или самодельными загрузчиками переводов, Intlayer предлагает интегрированный опыт разработки, оптимизированный для современной веб-архитектуры:
Intlayer разработан для естественной работы с веб-стандартами (Request, Response, Headers и URL). remix-intlayer подключается к роутеру Fetch Remix 3 как легковесное middleware, извлекая локаль из путей URL, cookie или заголовков Accept-Language и предоставляя ее остальной части запроса, обработчикам, представлениям и компонентам remix/ui, без необходимости передавать ее вручную или привязываться к определенной среде выполнения.
Забудьте о ненадежных строковых ключах JSON и ошибках отсутствия переводов во время выполнения. Intlayer обеспечивает строгую проверку TypeScript для всех объявленных локалей, предупреждая вас еще на этапе сборки, если перевод отсутствует или некорректен.
Remix 3 рендерит JSX-компоненты на сервере и передает HTML клиенту. В выходной поток отправляется только готовый текст для запрошенной локали. Никаких клиентских бандлов гидратации или тяжелых каталогов переводов не требуется, если компонент явно не помечен как clientEntry.
Intlayer размещает объявления контента (.content.ts) рядом с логикой маршрутов, сокращая объем контекста токенов для больших языковых моделей (LLM). Встроенные команды CLI, такие как intlayer fill и intlayer test, позволяют автоматизировать переводы в пайплайнах CI/CD по себестоимости выбранного провайдера ИИ.
Помимо работы через код, Intlayer предоставляет автономный Визуальный редактор и Удаленную CMS, позволяя редакторам и переводчикам обновлять контент без повторного развертывания проекта.
Пошаговое руководство
Посмотрите Шаблон приложения на GitHub.
Установка зависимостей
Установите
intlayer,remix-intlayerиremix(версия 3) с помощью предпочитаемого пакетного менеджера:bashКопировать кодКопировать код в буфер обмена
intlayer: Основной движок интернационализации, обеспечивающий управление конфигурацией, декларацию словарей (t(),Dictionary), утилиты CLI и рантайм-интерпретатор.remix-intlayer: Интеграция с Remix 3: middleware роутераintlayer(), разрешающее локаль каждого запроса, и хукиuseIntlayer,useDictionaryиuseLocale, считывающие ее ниже по цепочке.remix: Единый пакет фреймворка Remix 3, экспортирующийremix/router,remix/routes,remix/ui,remix/middleware/renderиremix/node-fetch-server.
Настройка Intlayer
Архитектура
В этой архитектуре middleware
intlayer()изremix-intlayerрегистрируется вcreateRouter()перед middlewarerender(). Он удаляет префикс локали до сопоставления маршрутизатора, поэтому маршруты объявляются один раз вsrc/routes.tsбез сегмента:locale, и выполняет остальную часть запроса внутри областиAsyncLocalStorage, что позволяетuseIntlayer/useLocaleчитать локаль без аргументов в обработчиках маршрутов и представленияхremix/ui. Объявления контента размещаются рядом с вашими представлениями вsrc/:bashКопировать кодКопировать код в буфер обмена
Конфигурация
Создайте файл
intlayer.config.tsв корне проекта для объявления поддерживаемых языков и параметров интернационализации:intlayer.config.tsКопировать кодКопировать код в буфер обмена
import { Locales, type IntlayerConfig } from "intlayer"; const config: IntlayerConfig = { internationalization: { locales: [ Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH, Locales.RUSSIAN, ], defaultLocale: Locales.ENGLISH, }, }; export default config;Дополнительные параметры конфигурации описаны в документации по настройке.
Объявление многоязычного контента
Объявите локализованный контент в файле
.content.ts:src/home.content.tsКопировать кодКопировать код в буфер обмена
import { t, type Dictionary } from "intlayer"; const homeContent = { key: "home", content: { title: t({ ru: "Добро пожаловать в Remix 3", en: "Welcome to Remix 3", fr: "Bienvenue sur Remix 3", es: "Bienvenido a Remix 3", }), description: t({ ru: "Модульное приложение на веб-стандартах со встроенной интернационализацией.", en: "A composable, web-standard application with native i18n.", fr: "Une application composable basée sur les standards web avec i18n native.", es: "Una aplicación componible basada en estándares web con i18n nativa.", }), switchLanguage: t({ ru: "Сменить язык:", en: "Switch language:", fr: "Changer de langue :", es: "Cambiar idioma:", }), }, } satisfies Dictionary; export default homeContent;Intlayer также поддерживает форматы JSON, YAML и CommonJS. См. Документацию по объявлению контента.
Сборка словарей Intlayer
Скомпилируйте объявления словарей для генерации типов TypeScript и реестров среды выполнения:
bashКопировать кодКопировать код в буфер обмена
Эта команда компилирует контент в каталог
.intlayer, обеспечивая автодополнение TypeScript и быстрый поиск по словарям.Добавление middleware Intlayer
Remix 3 предоставляет компонуемый конвейер middleware через
createRouter({ middleware: [...] }).remix-intlayerпоставляет middlewareintlayer(). Для каждого входящего запроса оно разрешает локаль, используя:- URL, во всех режимах маршрутизации, кроме
no-prefix: префикс пути (напр./ruили/en) или поисковый параметр?locale=. - Локаль, сохраненную клиентом: cookie хранилища (
INTLAYER_LOCALE) или пользовательский заголовок (x-intlayer-locale). - Стандартное согласование
Accept-Languageс возвратом к настроеннойdefaultLocale.
Результат сохраняется в контексте запроса Remix как
context.intlayer(илиcontext.get(Intlayer)), с полямиlocale,defaultLocaleиavailableLocales. Затем middleware выполняет остальную часть запроса в областиAsyncLocalStorage, привязанной к этому контексту, что позволяет хукам пакета считывать локаль без аргументов, в обработчиках маршрутов, представлениях и компонентахremix/ui:typescriptКопировать кодКопировать код в буфер обмена
useIntlayer("home", "fr")илиuseIntlayer("faq", { item: 2 })переопределяют локаль запроса для одного вызова, аuseDictionary(homeContent)считывает импортированный словарь вместо ключа. Вне контекста запроса хуки возвращаются к локали по умолчанию.Middleware также подготавливает словари Intlayer при запуске сервера, благодаря чему отсутствие
intlayer buildне оставит реестр пустым.Установите
routing.enableProxy: falseвintlayer.config.ts, чтобы оставить только определение локали и управлять маршрутизацией самостоятельно.intlayer({ ignore })не трогает совпадающие запросы (например, префикс API), аintlayer({ isDevServer })определяет, управляет ли сохранённая локаль редиректами в автоматическом режимеenableProxyпо умолчанию.- URL, во всех режимах маршрутизации, кроме
Определение типобезопасных маршрутов
Определите маршруты приложения с помощью
route()изremix/routes:src/routes.tsКопировать кодКопировать код в буфер обмена
import { route } from "remix/routes"; export const routes = route({ // Маршрут для локали по умолчанию home: "/", // Локализованный маршрут с динамическим сегментом :locale localizedHome: "/:locale", });Использование
route()обеспечивает типобезопасную генерацию URL по всему приложению:typescriptКопировать кодКопировать код в буфер обмена
Рендеринг локализованных страниц с JSX
Remix 3 рендерит пользовательский интерфейс с помощью JSX-компонентов из
remix/ui. Компонент представляет собой setup-функцию, которая принимаетHandleи возвращает функцию рендеринга. Setup выполняется один раз для каждого экземпляра, рендеринг запускается при каждом обновлении, а props считываются черезhandle.props.Начните с общей оболочки
Document, которая задает атрибуты<html lang="..." dir="...">на основе локали, разрешенной middleware:src/views/document.tsxКопировать кодКопировать код в буфер обмена
import { getHTMLTextDir } from "intlayer"; import { useLocale } from "remix-intlayer"; import type { Handle, RemixNode } from "remix/ui"; type DocumentProps = { title: string; children?: RemixNode; }; export const Document = (handle: Handle<DocumentProps>) => () => { const { title, children } = handle.props; const { locale } = useLocale(); return ( <html lang={locale} dir={getHTMLTextDir(locale)}> <head> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>{title}</title> </head> <body>{children}</body> </html> ); };Затем создайте главную страницу. Она считывает локализованный словарь с помощью
useIntlayerи отображает переключатель языков:src/views/home.tsxКопировать кодКопировать код в буфер обмена
import { getLocaleName, getLocalizedUrl, getPathWithoutLocale } from "intlayer"; import { useIntlayer, useLocale } from "remix-intlayer"; import { Document } from "./document"; export const HomePage = () => () => { const { locale, availableLocales } = useLocale(); const home = useIntlayer("home"); const pathWithoutLocale = getPathWithoutLocale(); return ( <Document title={home.title}> <header> <nav aria-label="Languages"> <span>{home.switchLanguage}</span> <ul> {availableLocales.map((localeItem) => { const isActive = localeItem === locale; return ( <li key={localeItem} class="p-1"> <a href={getLocalizedUrl(pathWithoutLocale, localeItem)} class={isActive ? "active" : undefined} aria-current={isActive ? "page" : undefined} > {getLocaleName(localeItem, locale)} </a> </li> ); })} </ul> </nav> </header> <main> <h1>{home.title}</h1> <p>{home.description}</p> </main> </Document> ); };JSX в Remix это не React:
classпишется как есть (classNameтакже поддерживается), а повторные рендеры вызываются явно черезhandle.update(). Интерполированные значения экранируются автоматически. Хуки Intlayer представляют собой простые функции, считывающие область запроса, поэтому их можно вызывать как из функции setup, так и из функции рендеринга.Подключение роутера и сервера
Добавьте middleware
render()изremix/middleware/renderрядом с middleware Intlayer. Оно добавляетcontext.render(node, init)к каждому запросу, передавая дерево JSX в HTMLResponse(добавляя в начало<!DOCTYPE html>и устанавливая заголовокContent-Type):src/router.tsxКопировать кодКопировать код в буфер обмена
import { isDeclaredLocale } from "intlayer"; import { intlayer } from "remix-intlayer"; import { render } from "remix/middleware/render"; import { createRouter } from "remix/router"; import { routes } from "./routes"; import { HomePage } from "./views/home"; // 1. Initialize router with Intlayer + render middleware export const router = createRouter({ middleware: [intlayer(), render()], }); // 2. Map route handlers router.map(routes, { actions: { // Default locale route home(context) { return context.render(<HomePage />); }, // Localized route localizedHome(context) { if (!isDeclaredLocale(context.params.locale)) { return new Response("Not Found", { status: 404 }); } return context.render(<HomePage />); }, }, });context.renderпринимает необязательныйResponseInitв качестве второго аргумента, напримерcontext.render(<NotFoundPage />, { status: 404 }). Разрешенная локаль остается доступной из обработчика какcontext.intlayer.locale, например для формирования ответаResponse.json.Наконец, экспортируйте роутер через стандартный обработчик
fetch. Один и тот же роутер работает на Node.js, Bun, Deno и Cloudflare Workers:src/server.tsКопировать кодКопировать код в буфер обмена
import * as http from "node:http"; import { createRequestListener } from "remix/node-fetch-server"; import { router } from "./router"; const PORT = Number(process.env.PORT || 3000); // Node.js const server = http.createServer( createRequestListener((request) => router.fetch(request)) ); server.listen(PORT, () => { console.log(`Сервер запущен по адресу http://localhost:${PORT}`); }); // Bun / Deno / Cloudflare Workers export default { port: PORT, fetch(request: Request) { return router.fetch(request); }, };Аудит и автоматическое заполнение переводов
Intlayer предоставляет CLI для поиска недостающих переводов и их автоматического заполнения с помощью ИИ:
bashКопировать кодКопировать код в буфер обмена
Конфигурация TypeScript
Настройте JSX на среду выполнения remix/ui и убедитесь, что ваш tsconfig.json включает сгенерированные типы .intlayer:
Копировать код в буфер обмена
jsxImportSource: "remix/ui"указывает, что<HomePage />разрешается в функциюcreateElementиз Remix, а не из React.
Заключение
Благодаря связке Remix 3 и Intlayer вы получаете легковесный, типобезопасный и кроссплатформенный стек, построенный на открытых веб-стандартах. Ваше приложение сможет легко масштабироваться от простых маркетинговых страниц до глобально распределенных сервисов с рендерингом на edge.
