Sorunuzu sorun ve bu sayfaya ve seçtiğiniz AI sağlayıcısına referans vererek belgenin bir özetini alın
Sürüm Geçmişi
- "Initial documentation for Remix 3"v9.5.009.09.2026
Bu sayfanın içeriği bir yapay zeka kullanılarak çevrildi.
Orijinal içeriğin İngilizce son sürümünü görüntüleyinBu dokümantasyonu geliştirmek için bir fikriniz varsa, lütfen GitHub'da bir çekme isteği göndererek katkıda bulunmaktan çekinmeyin.
Dokümantasyon için GitHub bağlantısıBelge Markdown'ını panoya kopyala
Translate your Remix 3 website using Intlayer | Internationalization (i18n)
This guide demonstrates how to integrate Intlayer for seamless internationalization in Remix 3 applications with locale-aware routing, type-safe content declarations, safe HTML templates, and cross-runtime support across Node.js, Bun, Deno, and Cloudflare Workers.
What is Remix 3?
Remix 3 represents a fundamental architectural shift towards a composable, runtime-agnostic web framework built entirely on web standards. Rather than being coupled to specific bundlers or proprietary server APIs, Remix 3 is distributed as single-purpose, composable packages:
remix/fetch-router(orremix/router): Lightweight, standard-compliant routing built on the Fetch API (RequestandResponse).remix/html-template: Safe HTML template literals with automatic XSS protection and fragment composition.remix/response/html: Response helper utilities for serving HTML with standard HTTP semantics.remix/node-fetch-server: Server adapters for Node.js, while natively supporting Bun, Deno, and edge runtimes.remix/cookie: Cryptographically secure cookie parsing and serialization.
Combined with Intlayer, you get a complete internationalization system that delivers compile-time safety, automated AI translations, zero-overhead server rendering, and seamless locale routing.
Table of Contents
Why Intlayer over alternatives?
Compared to traditional solutions like i18next or bespoke translation loaders, Intlayer offers an integrated developer experience optimized for modern web architecture:
Intlayer is built to work seamlessly with web standards (Request, Response, Headers, and URL). It integrates effortlessly into Remix 3's Fetch router through lightweight middleware, extracting locales from URL paths, cookies, or Accept-Language headers without locking you into a specific runtime.
Say goodbye to loose JSON keys and runtime missing-key crashes. Intlayer enforces TypeScript checks across all declared locales, warning you at build time if a translation is missing or invalid.
When using Remix 3's server-rendered HTML templates (remix/html-template), only the resolved text for the requested locale is rendered into the output stream. No client hydration bundles or bulky translation catalogs are needed unless explicitly required.
Intlayer co-locates content declarations (.content.ts) with your route logic, reducing the token context required by Large Language Models (LLMs). Built-in CLI commands like intlayer fill and intlayer test let you automate translations in CI/CD pipelines at the cost of your own AI provider.
Beyond code-first workflows, Intlayer provides a self-hosted Visual Editor and a Remote CMS allowing non-technical editors, translators, and copywriters to update content without redeploying code.
Step-by-Step Guide
See the Application Template on GitHub.
Install Dependencies
Install
intlayerandremix(version 3) using your preferred package manager:bashKodu kopyalaKodu panoya kopyala
intlayer: Core internationalization engine providing configuration management, dictionary declaration (t(),Dictionary), CLI tools, and runtime interpreter.remix: The unified Remix 3 framework package exportingremix/router,remix/routes,remix/html-template, andremix/node-fetch-server.
Configure Intlayer
Create an
intlayer.config.tsin the root of your project to declare your supported languages and internationalization settings:intlayer.config.tsKodu kopyalaKodu panoya kopyala
import { Locales, type IntlayerConfig } from "intlayer"; const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, }, }; export default config;For additional configuration settings (such as strict mode or routing storage preferences), refer to the configuration documentation.
Declare Your Multilingual Content
Declare your localized content in a
.content.tsfile:src/home.content.tsKodu kopyalaKodu panoya kopyala
import { t, type Dictionary } from "intlayer"; const homeContent = { key: "home", content: { title: t({ en: "Welcome to Remix 3", fr: "Bienvenue sur Remix 3", es: "Bienvenido a Remix 3", }), description: t({ 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({ en: "Switch language:", fr: "Changer de langue :", es: "Cambiar idioma:", }), }, } satisfies Dictionary; export default homeContent;Intlayer also supports JSON, YAML, and CommonJS declaration formats. See the Content Declaration Documentation.
Build Intlayer Dictionaries
Compile the dictionary definitions to generate TypeScript types and runtime registries:
bashKodu kopyalaKodu panoya kopyala
This compiles your content into the
.intlayerartifact directory, enabling full TypeScript autocompletion and rapid dictionary lookup.Implement the Intlayer Middleware
Remix 3 provides a composable middleware pipeline via
createRouter({ middleware: [...] }).Create an Intlayer middleware that resolves the locale of each incoming request using:
- The URL path prefix via Intlayer's
getLocaleFromPath(e.g./fror/es). - Intlayer's
getLocalehelper, which automatically negotiates across storage cookies (INTLAYER_LOCALE), custom headers (x-intlayer-locale), standardAccept-Languageheaders, and your configureddefaultLocale.
src/middleware/intlayer.tsKodu kopyalaKodu panoya kopyala
import { defaultLocale, getCookie, getLocale, getLocaleFromPath, type Locale, } from "intlayer"; import { createContextKey, type Middleware } from "remix/router"; /** * Type-safe context key to retrieve the resolved locale from Remix 3 RequestContext. */ export const localeKey = createContextKey<Locale>(defaultLocale); /** * Intlayer middleware for Remix 3. * * Resolves the request locale following priority: * 1. URL path prefix (e.g. `/fr/...`) via `getLocaleFromPath` * 2. Storage & headers negotiation via Intlayer `getLocale` (cookie, custom header, Accept-Language negotiation, fallback defaultLocale) * * Attaches the resolved locale to the Remix 3 RequestContext. */ export const intlayer = (): Middleware => { return async (context, next) => { // Path detection (/fr/about -> "fr", /about -> undefined) const pathLocale = getLocaleFromPath(context.url.pathname); if (pathLocale) { // Attach resolved locale to Remix 3 request context context.set(localeKey, pathLocale); return next(); } const storedLocale = await getLocale({ getHeader: (name) => context.headers.get(name), getCookie: (name) => getCookie(name, context.headers.get("cookie") ?? undefined), }); // Attach resolved locale to Remix 3 request context context.set(localeKey, storedLocale ?? defaultLocale); return next(); }; };- The URL path prefix via Intlayer's
Define Type-Safe Routes
Define your application routes using
route()fromremix/routes:src/routes.tsKodu kopyalaKodu panoya kopyala
import { route } from "remix/routes"; export const routes = route({ // Default locale route home: "/", // Localized route with dynamic :locale segment localizedHome: "/:locale", });Using
route()gives you type-safe URL generation across your application:typescriptKodu kopyalaKodu panoya kopyala
Render Localized HTML Templates
Remix 3 uses
remix/html-templatefor safe, auto-escaped HTML generation. Create a view function that extracts the localized dictionary usinggetIntlayer, sets the<html lang="..." dir="...">attributes, and displays a language switcher:src/views/home.tsKodu kopyalaKodu panoya kopyala
import { html, type SafeHtml } from "remix/html-template"; import { getIntlayer, getHTMLTextDir, getLocaleName, getLocalizedPath, type Locale, locales, } from "intlayer"; import { routes } from "../routes"; export const renderHomePage = (locale: Locale): SafeHtml => { const home = getIntlayer("home", locale); return html` <!doctype html> <html lang="${locale}" dir="${getHTMLTextDir(locale)}"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>${home.title}</title> </head> <body> <header> <nav aria-label="Languages"> <span>${home.switchLanguage}</span> ${locales.map((loc) => { const href = getLocalizedPath(routes.home.href(), loc); const isActive = loc === locale; return html` <a href="${href}" class="${isActive ? "active" : ""}" aria-current="${isActive ? "true" : "false"}" > ${getLocaleName(loc, locale)} </a> `; })} </nav> </header> <main> <h1>${home.title}</h1> <p>${home.description}</p> </main> </body> </html> `; };Wire Up the Server Application
Connect your router, middleware, and route actions together in
src/server.ts:src/server.tsKodu kopyalaKodu panoya kopyala
import * as http from "node:http"; import { createRouter } from "remix/router"; import { createRequestListener } from "remix/node-fetch-server"; import { createHtmlResponse } from "remix/response/html"; import { isDeclaredLocale } from "intlayer"; import { intlayer, localeKey } from "./middleware/intlayer"; import { routes } from "./routes"; import { renderHomePage } from "./views/home"; // 1. Initialize router with Intlayer middleware export const router = createRouter({ middleware: [intlayer()], }); // 2. Map route handlers router.map(routes, { actions: { // Default locale route home(context) { const locale = context.get(localeKey); return createHtmlResponse(renderHomePage(locale)); }, // Localized route localizedHome(context) { if (!isDeclaredLocale(context.params.locale)) { return new Response("Not Found", { status: 404 }); } const locale = context.get(localeKey); return createHtmlResponse(renderHomePage(locale)); }, }, }); // 3. Start server const PORT = Number(process.env.PORT || 3000); const server = http.createServer( createRequestListener((request) => router.fetch(request)) ); server.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}`); }); export default { port: PORT, fetch(request: Request) { return router.fetch(request); }, };Audit and Auto-Fill Translations
Intlayer provides a CLI to audit for missing translations and automatically fill them using AI:
bashKodu kopyalaKodu panoya kopyala
TypeScript Configuration
Ensure that your tsconfig.json includes the generated .intlayer types:
Kodu panoya kopyala
Conclusion
With Remix 3 and Intlayer, you have a lean, fully typed, runtime-portable stack that adheres to open web standards. Your application can scale effortlessly from simple localized marketing pages to globally distributed, edge-rendered services.
