@intlayer/docs 9.5.0 → 9.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/generated/docs.entry.cjs +20 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +20 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/intlayer_with_nextjs_15.md +1 -1
- package/docs/ar/intlayer_with_nextjs_16.md +1 -1
- package/docs/de/intlayer_with_nextjs_15.md +1 -1
- package/docs/de/intlayer_with_nextjs_16.md +1 -1
- package/docs/en/intlayer_with_nextjs_15.md +1 -1
- package/docs/en/intlayer_with_nextjs_16.md +1 -1
- package/docs/en/intlayer_with_remix_3.md +508 -0
- package/docs/en-GB/intlayer_with_nextjs_15.md +1 -1
- package/docs/en-GB/intlayer_with_nextjs_16.md +1 -1
- package/docs/es/intlayer_with_nextjs_15.md +1 -1
- package/docs/es/intlayer_with_nextjs_16.md +1 -1
- package/docs/fr/intlayer_with_nextjs_15.md +1 -1
- package/docs/fr/intlayer_with_nextjs_16.md +1 -1
- package/docs/hi/intlayer_with_nextjs_15.md +1 -1
- package/docs/hi/intlayer_with_nextjs_16.md +1 -1
- package/docs/id/intlayer_with_nextjs_15.md +1 -1
- package/docs/id/intlayer_with_nextjs_16.md +1 -1
- package/docs/it/intlayer_with_nextjs_15.md +1 -1
- package/docs/it/intlayer_with_nextjs_16.md +1 -1
- package/docs/ja/intlayer_with_nextjs_15.md +1 -1
- package/docs/ja/intlayer_with_nextjs_16.md +1 -1
- package/docs/pl/intlayer_with_nextjs_15.md +1 -1
- package/docs/pl/intlayer_with_nextjs_16.md +1 -1
- package/docs/pt/intlayer_with_nextjs_15.md +1 -1
- package/docs/pt/intlayer_with_nextjs_16.md +1 -1
- package/docs/ru/intlayer_with_nextjs_15.md +1 -1
- package/docs/ru/intlayer_with_nextjs_16.md +1 -1
- package/docs/tr/intlayer_with_nextjs_15.md +1 -1
- package/docs/tr/intlayer_with_nextjs_16.md +1 -1
- package/docs/uk/intlayer_with_nextjs_15.md +1 -1
- package/docs/uk/intlayer_with_nextjs_16.md +1 -1
- package/docs/vi/intlayer_with_nextjs_15.md +1 -1
- package/docs/vi/intlayer_with_nextjs_16.md +1 -1
- package/docs/zh/intlayer_with_nextjs_15.md +1 -1
- package/docs/zh/intlayer_with_nextjs_16.md +1 -1
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +20 -0
|
@@ -106,6 +106,7 @@ export declare const docsEntry: {
|
|
|
106
106
|
readonly './docs/en/intlayer_with_nuxt.md': Record<LocalesValues, Promise<string>>;
|
|
107
107
|
readonly './docs/en/intlayer_with_react_native+expo.md': Record<LocalesValues, Promise<string>>;
|
|
108
108
|
readonly './docs/en/intlayer_with_react_router_v7.md': Record<LocalesValues, Promise<string>>;
|
|
109
|
+
readonly './docs/en/intlayer_with_remix_3.md': Record<LocalesValues, Promise<string>>;
|
|
109
110
|
readonly './docs/en/intlayer_with_solid_start.md': Record<LocalesValues, Promise<string>>;
|
|
110
111
|
readonly './docs/en/intlayer_with_storybook.md': Record<LocalesValues, Promise<string>>;
|
|
111
112
|
readonly './docs/en/intlayer_with_svelte_kit.md': Record<LocalesValues, Promise<string>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.entry.d.ts","names":[],"sources":["../../../src/generated/docs.entry.ts"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"docs.entry.d.ts","names":[],"sources":["../../../src/generated/docs.entry.ts"],"mappings":";;qBAsFa;WACX,sBAmBgB,OAAO,eAAe;WACtC,6BAmBgB,OAAO,eAAe;WACtC,0BAmBgB,OAAO,eAAe;WACtC,yBAmBgB,OAAO,eAAe;WACtC,gCAmBgB,OAAO,eAAe;WACtC,iCAmBgB,OAAO,eAAe;WACtC,gCAmBgB,OAAO,eAAe;WACtC,iCAmBgB,OAAO,eAAe;WACtC,mCAmBgB,OAAO,eAAe;WACtC,8BAmBgB,OAAO,eAAe;WACtC,oCAmBgB,OAAO,eAAe;WACtC,0BAmBgB,OAAO,eAAe;WACtC,uBAmBgB,OAAO,eAAe;WACtC,kCAmBgB,OAAO,eAAe;WACtC,0BAmBgB,OAAO,eAAe;WACtC,+BAmBgB,OAAO,eAAe;WACtC,kCAmBgB,OAAO,eAAe;WACtC,2BAmBgB,OAAO,eAAe;WACtC,4BAmBgB,OAAO,eAAe;WACtC,yBAmBgB,OAAO,eAAe;WACtC,0BAmBgB,OAAO,eAAe;WACtC,yBAmBgB,OAAO,eAAe;WACtC,yBAmBgB,OAAO,eAAe;WACtC,kCAmBgB,OAAO,eAAe;WACtC,yBAmBgB,OAAO,eAAe;WACtC,0BAmBgB,OAAO,eAAe;WACtC,yBAmBgB,OAAO,eAAe;WACtC,yBAmBgB,OAAO,eAAe;WACtC,yBAmBgB,OAAO,eAAe;WACtC,wBAmBgB,OAAO,eAAe;WACtC,+BAmBgB,OAAO,eAAe;WACtC,yBAmBgB,OAAO,eAAe;WACtC,4BAmBgB,OAAO,eAAe;WACtC,0BAmBgB,OAAO,eAAe;WACtC,+BAmBgB,OAAO,eAAe;WACtC,+BAmBgB,OAAO,eAAe;WACtC,6BAmBgB,OAAO,eAAe;WACtC,8BAmBgB,OAAO,eAAe;WACtC,oCAmBgB,OAAO,eAAe;WACtC,iCAmBgB,OAAO,eAAe;WACtC,sCAmBgB,OAAO,eAAe;WACtC,qCAmBgB,OAAO,eAAe;WACtC,mCAmBgB,OAAO,eAAe;WACtC,gCAmBgB,OAAO,eAAe;WACtC,qCAmBgB,OAAO,eAAe;WACtC,kCAmBgB,OAAO,eAAe;WACtC,mCAmBgB,OAAO,eAAe;WACtC,iCAmBgB,OAAO,eAAe;WACtC,gCAmBgB,OAAO,eAAe;WACtC,yBAmBgB,OAAO,eAAe;WACtC,+BAmBgB,OAAO,eAAe;WACtC,8BAmBgB,OAAO,eAAe;WACtC,+BAmBgB,OAAO,eAAe;WACtC,oCAmBgB,OAAO,eAAe;WACtC,qCAmBgB,OAAO,eAAe;WACtC,wCAmBgB,OAAO,eAAe;WACtC,uCAmBgB,OAAO,eAAe;WACtC,gCAmBgB,OAAO,eAAe;WACtC,6CAmBgB,OAAO,eAAe;WACtC,kCAmBgB,OAAO,eAAe;WACtC,gCAmBgB,OAAO,eAAe;WACtC,qCAmBgB,OAAO,eAAe;WACtC,oCAmBgB,OAAO,eAAe;WACtC,mCAmBgB,OAAO,eAAe;WACtC,mCAmBgB,OAAO,eAAe;WACtC,kCAmBgB,OAAO,eAAe;WACtC,uCAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,2CAmBgB,OAAO,eAAe;WACtC,8CAmBgB,OAAO,eAAe;WACtC,uBAmBgB,OAAO,eAAe;WACtC,2BAmBgB,OAAO,eAAe;WACtC,mCAmBgB,OAAO,eAAe;WACtC,qCAmBgB,OAAO,eAAe;WACtC,6BAmBgB,OAAO,eAAe;WACtC,uCAmBgB,OAAO,eAAe;WACtC,uCAmBgB,OAAO,eAAe;WACtC,qCAmBgB,OAAO,eAAe;WACtC,yCAmBgB,OAAO,eAAe;WACtC,yCAmBgB,OAAO,eAAe;WACtC,oCAmBgB,OAAO,eAAe;WACtC,wCAmBgB,OAAO,eAAe;WACtC,2CAmBgB,OAAO,eAAe;WACtC,0CAmBgB,OAAO,eAAe;WACtC,0CAmBgB,OAAO,eAAe;WACtC,2CAmBgB,OAAO,eAAe;WACtC,4CAmBgB,OAAO,eAAe;WACtC,wCAmBgB,OAAO,eAAe;WACtC,+CAmBgB,OAAO,eAAe;WACtC,qCAmBgB,OAAO,eAAe;WACtC,sCAmBgB,OAAO,eAAe;WACtC,sCAmBgB,OAAO,eAAe;WACtC,mCAmBgB,OAAO,eAAe;WACtC,mCAmBgB,OAAO,eAAe;WACtC,yCAmBgB,OAAO,eAAe;WACtC,qCAmBgB,OAAO,eAAe;WACtC,2CAmBgB,OAAO,eAAe;WACtC,wCAmBgB,OAAO,eAAe;WACtC,wCAmBgB,OAAO,eAAe;WACtC,wCAmBgB,OAAO,eAAe;WACtC,wCAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,mCAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,8CAmBgB,OAAO,eAAe;WACtC,sCAmBgB,OAAO,eAAe;WACtC,0CAmBgB,OAAO,eAAe;WACtC,wCAmBgB,OAAO,eAAe;WACtC,yCAmBgB,OAAO,eAAe;WACtC,6CAmBgB,OAAO,eAAe;WACtC,uCAmBgB,OAAO,eAAe;WACtC,sCAmBgB,OAAO,eAAe;WACtC,uCAmBgB,OAAO,eAAe;WACtC,0CAmBgB,OAAO,eAAe;WACtC,yCAmBgB,OAAO,eAAe;WACtC,yCAmBgB,OAAO,eAAe;WACtC,0CAmBgB,OAAO,eAAe;WACtC,2CAmBgB,OAAO,eAAe;WACtC,uCAmBgB,OAAO,eAAe;WACtC,6BAmBgB,OAAO,eAAe;WACtC,0BAmBgB,OAAO,eAAe;WACtC,8BAmBgB,OAAO,eAAe;WACtC,oBAmBgB,OAAO,eAAe;WACtC,2BAmBgB,OAAO,eAAe;WACtC,mDAmBgB,OAAO,eAAe;WACtC,wDAmBgB,OAAO,eAAe;WACtC,qDAmBgB,OAAO,eAAe;WACtC,uDAmBgB,OAAO,eAAe;WACtC,yDAmBgB,OAAO,eAAe;WACtC,oDAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,kDAmBgB,OAAO,eAAe;WACtC,2CAmBgB,OAAO,eAAe;WACtC,kDAmBgB,OAAO,eAAe;WACtC,sDAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,kDAmBgB,OAAO,eAAe;WACtC,kDAmBgB,OAAO,eAAe;WACtC,mDAmBgB,OAAO,eAAe;WACtC,4CAmBgB,OAAO,eAAe;WACtC,kDAmBgB,OAAO,eAAe;WACtC,mDAmBgB,OAAO,eAAe;WACtC,+CAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,yCAmBgB,OAAO,eAAe;WACtC,8CAmBgB,OAAO,eAAe;WACtC,+CAmBgB,OAAO,eAAe;WACtC,0CAmBgB,OAAO,eAAe;WACtC,mDAmBgB,OAAO,eAAe;WACtC,mDAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,qDAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,8CAmBgB,OAAO,eAAe;WACtC,mDAmBgB,OAAO,eAAe;WACtC,4CAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,mDAmBgB,OAAO,eAAe;WACtC,kDAmBgB,OAAO,eAAe;WACtC,sDAmBgB,OAAO,eAAe;WACtC,uDAmBgB,OAAO,eAAe;WACtC,4CAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,+CAmBgB,OAAO,eAAe;WACtC,+CAmBgB,OAAO,eAAe;WACtC,0DAsBgB,OAAO,eAAe;WACtC,yCAmBgB,OAAO,eAAe;WACtC,qDAmBgB,OAAO,eAAe;WACtC,mDAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,mDAmBgB,OAAO,eAAe;WACtC,qDAmBgB,OAAO,eAAe;WACtC,+CAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,qDAmBgB,OAAO,eAAe;WACtC,yDAmBgB,OAAO,eAAe;WACtC,yDAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,0CAmBgB,OAAO,eAAe;WACtC,sDAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,oDAmBgB,OAAO,eAAe;WACtC,kDAmBgB,OAAO,eAAe;WACtC,oDAmBgB,OAAO,eAAe;WACtC,sDAmBgB,OAAO,eAAe;WACtC,uDAmBgB,OAAO,eAAe;WACtC,yDAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,oDAmBgB,OAAO,eAAe;WACtC,kDAmBgB,OAAO,eAAe;WACtC,oDAmBgB,OAAO,eAAe;WACtC,sDAmBgB,OAAO,eAAe;WACtC,iDAmBgB,OAAO,eAAe;WACtC,qDAmBgB,OAAO,eAAe;WACtC,uDAmBgB,OAAO,eAAe;WACtC,+CAmBgB,OAAO,eAAe;WACtC,gDAmBgB,OAAO,eAAe;WACtC,wDAmBgB,OAAO,eAAe;WACtC,sDAmBgB,OAAO,eAAe;WACtC,qDAmBgB,OAAO,eAAe;WACtC,qDAmBgB,OAAO,eAAe;WACtC,8CAmBgB,OAAO,eAAe;WACtC,kDAmBgB,OAAO,eAAe;WACtC,oDAmBgB,OAAO,eAAe;WACtC,gCAmBgB,OAAO,eAAe;WACtC,kCAmBgB,OAAO,eAAe;WACtC,gCAmBgB,OAAO,eAAe;WACtC,uBAmBgB,OAAO,eAAe;WACtC,4BAmBgB,OAAO,eAAe;WACtC,4BAmBgB,OAAO,eAAe;WACtC,4BAmBgB,OAAO,eAAe;WACtC,4BAmBgB,OAAO,eAAe;WACtC,wBAmBgB,OAAO,eAAe;WACtC,6BAmBgB,OAAO,eAAe;WACtC,wBAmBgB,OAAO,eAAe;WACtC,kCAmBgB,OAAO,eAAe"}
|
|
@@ -978,7 +978,7 @@ bun add @intlayer/swc --dev
|
|
|
978
978
|
<Tabs>
|
|
979
979
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
980
980
|
|
|
981
|
-
منذ إصدار
|
|
981
|
+
منذ إصدار next-intlayer v9.5، يبدأ `withIntlayer` مراقب المحتوى (content watcher) تلقائياً، ولا حاجة لأي إعداد إضافي.
|
|
982
982
|
|
|
983
983
|
</Tab>
|
|
984
984
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -1277,7 +1277,7 @@ bun run build # أو bun run dev
|
|
|
1277
1277
|
<Tabs>
|
|
1278
1278
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
1279
1279
|
|
|
1280
|
-
منذ إصدار
|
|
1280
|
+
منذ إصدار next-intlayer v9.5، يبدأ `withIntlayer` مراقب المحتوى (content watcher) تلقائياً، ولا حاجة لأي إعداد إضافي.
|
|
1281
1281
|
|
|
1282
1282
|
</Tab>
|
|
1283
1283
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -977,7 +977,7 @@ bun add @intlayer/swc --dev
|
|
|
977
977
|
<Tabs>
|
|
978
978
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
979
979
|
|
|
980
|
-
Seit
|
|
980
|
+
Seit next-intlayer v9.5 startet `withIntlayer` den Content Watcher selbst, keine zusätzliche Konfiguration erforderlich.
|
|
981
981
|
|
|
982
982
|
</Tab>
|
|
983
983
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -1297,7 +1297,7 @@ bun run build # Or bun run dev
|
|
|
1297
1297
|
<Tabs>
|
|
1298
1298
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
1299
1299
|
|
|
1300
|
-
Seit
|
|
1300
|
+
Seit next-intlayer v9.5 startet `withIntlayer` den Content Watcher selbst, keine zusätzliche Konfiguration erforderlich.
|
|
1301
1301
|
|
|
1302
1302
|
</Tab>
|
|
1303
1303
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -997,7 +997,7 @@ bun add @intlayer/swc --dev
|
|
|
997
997
|
<Tabs>
|
|
998
998
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
999
999
|
|
|
1000
|
-
Since
|
|
1000
|
+
Since next-intlayer v9.5, `withIntlayer` starts the content watcher itself, no need extra set up.
|
|
1001
1001
|
|
|
1002
1002
|
</Tab>
|
|
1003
1003
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -1276,7 +1276,7 @@ bun run build # Or bun run dev
|
|
|
1276
1276
|
<Tabs>
|
|
1277
1277
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
1278
1278
|
|
|
1279
|
-
Since
|
|
1279
|
+
Since next-intlayer v9.5, `withIntlayer` starts the content watcher itself, no need extra set up.
|
|
1280
1280
|
|
|
1281
1281
|
</Tab>
|
|
1282
1282
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-09-09
|
|
3
|
+
updatedAt: 2026-09-09
|
|
4
|
+
title: "Remix 3 i18n - Complete guide to translate your app"
|
|
5
|
+
description: "No more i18next. The 2026 guide to building a multilingual (i18n) Remix 3 app. Translate with AI agents and optimize bundle size, SEO and performances."
|
|
6
|
+
keywords:
|
|
7
|
+
- Internationalization
|
|
8
|
+
- Documentation
|
|
9
|
+
- Intlayer
|
|
10
|
+
- Remix 3
|
|
11
|
+
- Remix
|
|
12
|
+
- JavaScript
|
|
13
|
+
- TypeScript
|
|
14
|
+
- Web Standards
|
|
15
|
+
slugs:
|
|
16
|
+
- doc
|
|
17
|
+
- environment
|
|
18
|
+
- remix-3
|
|
19
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-remix-3-template
|
|
20
|
+
applicationShowcase: https://intlayer-remix-3-template.vercel.app
|
|
21
|
+
history:
|
|
22
|
+
- version: 9.5.0
|
|
23
|
+
date: 2026-09-09
|
|
24
|
+
changes: "Initial documentation for Remix 3"
|
|
25
|
+
author: aymericzip
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
# Translate your Remix 3 website using Intlayer | Internationalization (i18n)
|
|
29
|
+
|
|
30
|
+
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.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## What is Remix 3?
|
|
35
|
+
|
|
36
|
+
**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:
|
|
37
|
+
|
|
38
|
+
- **`remix/fetch-router`** (or `remix/router`): Lightweight, standard-compliant routing built on the Fetch API (`Request` and `Response`).
|
|
39
|
+
- **`remix/html-template`**: Safe HTML template literals with automatic XSS protection and fragment composition.
|
|
40
|
+
- **`remix/response/html`**: Response helper utilities for serving HTML with standard HTTP semantics.
|
|
41
|
+
- **`remix/node-fetch-server`**: Server adapters for Node.js, while natively supporting Bun, Deno, and edge runtimes.
|
|
42
|
+
- **`remix/cookie`**: Cryptographically secure cookie parsing and serialization.
|
|
43
|
+
|
|
44
|
+
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.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Table of Contents
|
|
49
|
+
|
|
50
|
+
<TOC/>
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Why Intlayer over alternatives?
|
|
55
|
+
|
|
56
|
+
Compared to traditional solutions like `i18next` or bespoke translation loaders, Intlayer offers an integrated developer experience optimized for modern web architecture:
|
|
57
|
+
|
|
58
|
+
<AccordionGroup>
|
|
59
|
+
<Accordion header="Full Remix 3 & Web Standards Coverage">
|
|
60
|
+
|
|
61
|
+
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.
|
|
62
|
+
|
|
63
|
+
</Accordion>
|
|
64
|
+
<Accordion header="Type-Safe Content Declarations">
|
|
65
|
+
|
|
66
|
+
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.
|
|
67
|
+
|
|
68
|
+
</Accordion>
|
|
69
|
+
<Accordion header="Zero Bundle Overhead on the Server">
|
|
70
|
+
|
|
71
|
+
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.
|
|
72
|
+
|
|
73
|
+
</Accordion>
|
|
74
|
+
<Accordion header="AI Agent & Automation Ready">
|
|
75
|
+
|
|
76
|
+
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.
|
|
77
|
+
|
|
78
|
+
</Accordion>
|
|
79
|
+
<Accordion header="Visual Editor & CMS Integration">
|
|
80
|
+
|
|
81
|
+
Beyond code-first workflows, Intlayer provides a self-hosted [Visual Editor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_visual_editor.md) and a [Remote CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_CMS.md) allowing non-technical editors, translators, and copywriters to update content without redeploying code.
|
|
82
|
+
|
|
83
|
+
</Accordion>
|
|
84
|
+
</AccordionGroup>
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Step-by-Step Guide
|
|
89
|
+
|
|
90
|
+
<Tabs defaultTab="code">
|
|
91
|
+
<Tab label="Code" value="code">
|
|
92
|
+
|
|
93
|
+
<iframe
|
|
94
|
+
src="https://ide.intlayer.org/aymericzip/intlayer-remix-3-template?file=intlayer.config.ts"
|
|
95
|
+
className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
|
|
96
|
+
title="Demo CodeSandbox - How to Internationalize your application using Intlayer"
|
|
97
|
+
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
|
98
|
+
loading="lazy"
|
|
99
|
+
/>
|
|
100
|
+
|
|
101
|
+
</Tab>
|
|
102
|
+
<Tab label="Demo" value="demo">
|
|
103
|
+
|
|
104
|
+
<iframe
|
|
105
|
+
src="https://intlayer-remix-3-template.vercel.app"
|
|
106
|
+
className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
|
|
107
|
+
title="Demo Intlayer Remix 3 Template"
|
|
108
|
+
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
|
109
|
+
loading="lazy"
|
|
110
|
+
/>
|
|
111
|
+
|
|
112
|
+
</Tab>
|
|
113
|
+
</Tabs>
|
|
114
|
+
|
|
115
|
+
See the [Application Template](https://github.com/aymericzip/intlayer-remix-3-template) on GitHub.
|
|
116
|
+
|
|
117
|
+
<Steps>
|
|
118
|
+
<Step number={1} title="Install Dependencies">
|
|
119
|
+
|
|
120
|
+
Install `intlayer` and `remix` (version 3) using your preferred package manager:
|
|
121
|
+
|
|
122
|
+
```bash packageManager="npm"
|
|
123
|
+
npm install intlayer remix@next
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
```bash packageManager="pnpm"
|
|
127
|
+
pnpm add intlayer remix@next
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```bash packageManager="yarn"
|
|
131
|
+
yarn add intlayer remix@next
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```bash packageManager="bun"
|
|
135
|
+
bun add intlayer remix@next
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- **`intlayer`**: Core internationalization engine providing configuration management, dictionary declaration (`t()`, `Dictionary`), CLI tools, and runtime interpreter.
|
|
139
|
+
- **`remix`**: The unified Remix 3 framework package exporting `remix/router`, `remix/routes`, `remix/html-template`, and `remix/node-fetch-server`.
|
|
140
|
+
|
|
141
|
+
</Step>
|
|
142
|
+
<Step number={2} title="Configure Intlayer">
|
|
143
|
+
|
|
144
|
+
Create an `intlayer.config.ts` in the root of your project to declare your supported languages and internationalization settings:
|
|
145
|
+
|
|
146
|
+
```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
|
|
147
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
148
|
+
|
|
149
|
+
const config: IntlayerConfig = {
|
|
150
|
+
internationalization: {
|
|
151
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
152
|
+
defaultLocale: Locales.ENGLISH,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export default config;
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
```javascript fileName="intlayer.config.mjs" codeFormat="esm"
|
|
160
|
+
import { Locales } from "intlayer";
|
|
161
|
+
|
|
162
|
+
/** @type {import('intlayer').IntlayerConfig} */
|
|
163
|
+
const config = {
|
|
164
|
+
internationalization: {
|
|
165
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
166
|
+
defaultLocale: Locales.ENGLISH,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export default config;
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```javascript fileName="intlayer.config.cjs" codeFormat="commonjs"
|
|
174
|
+
const { Locales } = require("intlayer");
|
|
175
|
+
|
|
176
|
+
/** @type {import('intlayer').IntlayerConfig} */
|
|
177
|
+
const config = {
|
|
178
|
+
internationalization: {
|
|
179
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
180
|
+
defaultLocale: Locales.ENGLISH,
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
module.exports = config;
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
> For additional configuration settings (such as strict mode or routing storage preferences), refer to the [configuration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/configuration.md).
|
|
188
|
+
|
|
189
|
+
</Step>
|
|
190
|
+
<Step number={3} title="Declare Your Multilingual Content">
|
|
191
|
+
|
|
192
|
+
Declare your localized content in a `.content.ts` file:
|
|
193
|
+
|
|
194
|
+
```typescript fileName="src/home.content.ts" contentDeclarationFormat={["typescript", "esm"]}
|
|
195
|
+
import { t, type Dictionary } from "intlayer";
|
|
196
|
+
|
|
197
|
+
const homeContent = {
|
|
198
|
+
key: "home",
|
|
199
|
+
content: {
|
|
200
|
+
title: t({
|
|
201
|
+
en: "Welcome to Remix 3",
|
|
202
|
+
fr: "Bienvenue sur Remix 3",
|
|
203
|
+
es: "Bienvenido a Remix 3",
|
|
204
|
+
}),
|
|
205
|
+
description: t({
|
|
206
|
+
en: "A composable, web-standard application with native i18n.",
|
|
207
|
+
fr: "Une application composable basée sur les standards web avec i18n native.",
|
|
208
|
+
es: "Una aplicación componible basada en estándares web con i18n nativa.",
|
|
209
|
+
}),
|
|
210
|
+
switchLanguage: t({
|
|
211
|
+
en: "Switch language:",
|
|
212
|
+
fr: "Changer de langue :",
|
|
213
|
+
es: "Cambiar idioma:",
|
|
214
|
+
}),
|
|
215
|
+
},
|
|
216
|
+
} satisfies Dictionary;
|
|
217
|
+
|
|
218
|
+
export default homeContent;
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
> Intlayer also supports JSON, YAML, and CommonJS declaration formats. See the [Content Declaration Documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/dictionary/content_file.md).
|
|
222
|
+
|
|
223
|
+
</Step>
|
|
224
|
+
<Step number={4} title="Build Intlayer Dictionaries">
|
|
225
|
+
|
|
226
|
+
Compile the dictionary definitions to generate TypeScript types and runtime registries:
|
|
227
|
+
|
|
228
|
+
```bash packageManager="npm"
|
|
229
|
+
npx intlayer build
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
```bash packageManager="pnpm"
|
|
233
|
+
pnpm dlx intlayer build
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```bash packageManager="yarn"
|
|
237
|
+
yarn dlx intlayer build
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
```bash packageManager="bun"
|
|
241
|
+
bun x intlayer build
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
This compiles your content into the `.intlayer` artifact directory, enabling full TypeScript autocompletion and rapid dictionary lookup.
|
|
245
|
+
|
|
246
|
+
</Step>
|
|
247
|
+
<Step number={5} title="Implement the Intlayer Middleware">
|
|
248
|
+
|
|
249
|
+
Remix 3 provides a composable middleware pipeline via `createRouter({ middleware: [...] })`.
|
|
250
|
+
|
|
251
|
+
Create an Intlayer middleware that resolves the locale of each incoming request using:
|
|
252
|
+
|
|
253
|
+
1. The URL path prefix via Intlayer's `getLocaleFromPath` (e.g. `/fr` or `/es`).
|
|
254
|
+
2. Intlayer's `getLocale` helper, which automatically negotiates across storage cookies (`INTLAYER_LOCALE`), custom headers (`x-intlayer-locale`), standard `Accept-Language` headers, and your configured `defaultLocale`.
|
|
255
|
+
|
|
256
|
+
```typescript fileName="src/middleware/intlayer.ts" codeFormat={["typescript", "esm"]}
|
|
257
|
+
import {
|
|
258
|
+
defaultLocale,
|
|
259
|
+
getCookie,
|
|
260
|
+
getLocale,
|
|
261
|
+
getLocaleFromPath,
|
|
262
|
+
type Locale,
|
|
263
|
+
} from "intlayer";
|
|
264
|
+
import { createContextKey, type Middleware } from "remix/router";
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Type-safe context key to retrieve the resolved locale from Remix 3 RequestContext.
|
|
268
|
+
*/
|
|
269
|
+
export const localeKey = createContextKey<Locale>(defaultLocale);
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Intlayer middleware for Remix 3.
|
|
273
|
+
*
|
|
274
|
+
* Resolves the request locale following priority:
|
|
275
|
+
* 1. URL path prefix (e.g. `/fr/...`) via `getLocaleFromPath`
|
|
276
|
+
* 2. Storage & headers negotiation via Intlayer `getLocale` (cookie, custom header, Accept-Language negotiation, fallback defaultLocale)
|
|
277
|
+
*
|
|
278
|
+
* Attaches the resolved locale to the Remix 3 RequestContext.
|
|
279
|
+
*/
|
|
280
|
+
export const intlayer = (): Middleware => {
|
|
281
|
+
return async (context, next) => {
|
|
282
|
+
// Path detection (/fr/about -> "fr", /about -> undefined)
|
|
283
|
+
const pathLocale = getLocaleFromPath(context.url.pathname);
|
|
284
|
+
|
|
285
|
+
if (pathLocale) {
|
|
286
|
+
// Attach resolved locale to Remix 3 request context
|
|
287
|
+
context.set(localeKey, pathLocale);
|
|
288
|
+
|
|
289
|
+
return next();
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const storedLocale = await getLocale({
|
|
293
|
+
getHeader: (name) => context.headers.get(name),
|
|
294
|
+
getCookie: (name) =>
|
|
295
|
+
getCookie(name, context.headers.get("cookie") ?? undefined),
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Attach resolved locale to Remix 3 request context
|
|
299
|
+
context.set(localeKey, storedLocale ?? defaultLocale);
|
|
300
|
+
|
|
301
|
+
return next();
|
|
302
|
+
};
|
|
303
|
+
};
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
</Step>
|
|
307
|
+
<Step number={6} title="Define Type-Safe Routes">
|
|
308
|
+
|
|
309
|
+
Define your application routes using `route()` from `remix/routes`:
|
|
310
|
+
|
|
311
|
+
```typescript fileName="src/routes.ts" codeFormat={["typescript", "esm"]}
|
|
312
|
+
import { route } from "remix/routes";
|
|
313
|
+
|
|
314
|
+
export const routes = route({
|
|
315
|
+
// Default locale route
|
|
316
|
+
home: "/",
|
|
317
|
+
|
|
318
|
+
// Localized route with dynamic :locale segment
|
|
319
|
+
localizedHome: "/:locale",
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Using `route()` gives you type-safe URL generation across your application:
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
routes.home.href(); // "/"
|
|
327
|
+
routes.localizedHome.href({ locale: "fr" }); // "/fr"
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
</Step>
|
|
331
|
+
<Step number={7} title="Render Localized HTML Templates">
|
|
332
|
+
|
|
333
|
+
Remix 3 uses `remix/html-template` for safe, auto-escaped HTML generation. Create a view function that extracts the localized dictionary using `getIntlayer`, sets the `<html lang="..." dir="...">` attributes, and displays a language switcher:
|
|
334
|
+
|
|
335
|
+
```typescript fileName="src/views/home.ts" codeFormat={["typescript", "esm"]}
|
|
336
|
+
import { html, type SafeHtml } from "remix/html-template";
|
|
337
|
+
import {
|
|
338
|
+
getIntlayer,
|
|
339
|
+
getHTMLTextDir,
|
|
340
|
+
getLocaleName,
|
|
341
|
+
getLocalizedPath,
|
|
342
|
+
type Locale,
|
|
343
|
+
locales,
|
|
344
|
+
} from "intlayer";
|
|
345
|
+
import { routes } from "../routes";
|
|
346
|
+
|
|
347
|
+
export const renderHomePage = (locale: Locale): SafeHtml => {
|
|
348
|
+
const home = getIntlayer("home", locale);
|
|
349
|
+
|
|
350
|
+
return html`
|
|
351
|
+
<!doctype html>
|
|
352
|
+
<html lang="${locale}" dir="${getHTMLTextDir(locale)}">
|
|
353
|
+
<head>
|
|
354
|
+
<meta charset="utf-8" />
|
|
355
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
356
|
+
<title>${home.title}</title>
|
|
357
|
+
</head>
|
|
358
|
+
<body>
|
|
359
|
+
<header>
|
|
360
|
+
<nav aria-label="Languages">
|
|
361
|
+
<span>${home.switchLanguage}</span>
|
|
362
|
+
${locales.map((loc) => {
|
|
363
|
+
const href = getLocalizedPath(routes.home.href(), loc);
|
|
364
|
+
const isActive = loc === locale;
|
|
365
|
+
return html`
|
|
366
|
+
<a
|
|
367
|
+
href="${href}"
|
|
368
|
+
class="${isActive ? "active" : ""}"
|
|
369
|
+
aria-current="${isActive ? "true" : "false"}"
|
|
370
|
+
>
|
|
371
|
+
${getLocaleName(loc, locale)}
|
|
372
|
+
</a>
|
|
373
|
+
`;
|
|
374
|
+
})}
|
|
375
|
+
</nav>
|
|
376
|
+
</header>
|
|
377
|
+
<main>
|
|
378
|
+
<h1>${home.title}</h1>
|
|
379
|
+
<p>${home.description}</p>
|
|
380
|
+
</main>
|
|
381
|
+
</body>
|
|
382
|
+
</html>
|
|
383
|
+
`;
|
|
384
|
+
};
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
</Step>
|
|
388
|
+
<Step number={8} title="Wire Up the Server Application">
|
|
389
|
+
|
|
390
|
+
Connect your router, middleware, and route actions together in `src/server.ts`:
|
|
391
|
+
|
|
392
|
+
```typescript fileName="src/server.ts" codeFormat={["typescript", "esm"]}
|
|
393
|
+
import * as http from "node:http";
|
|
394
|
+
import { createRouter } from "remix/router";
|
|
395
|
+
import { createRequestListener } from "remix/node-fetch-server";
|
|
396
|
+
import { createHtmlResponse } from "remix/response/html";
|
|
397
|
+
import { isDeclaredLocale } from "intlayer";
|
|
398
|
+
import { intlayer, localeKey } from "./middleware/intlayer";
|
|
399
|
+
import { routes } from "./routes";
|
|
400
|
+
import { renderHomePage } from "./views/home";
|
|
401
|
+
|
|
402
|
+
// 1. Initialize router with Intlayer middleware
|
|
403
|
+
export const router = createRouter({
|
|
404
|
+
middleware: [intlayer()],
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// 2. Map route handlers
|
|
408
|
+
router.map(routes, {
|
|
409
|
+
actions: {
|
|
410
|
+
// Default locale route
|
|
411
|
+
home(context) {
|
|
412
|
+
const locale = context.get(localeKey);
|
|
413
|
+
return createHtmlResponse(renderHomePage(locale));
|
|
414
|
+
},
|
|
415
|
+
|
|
416
|
+
// Localized route
|
|
417
|
+
localizedHome(context) {
|
|
418
|
+
if (!isDeclaredLocale(context.params.locale)) {
|
|
419
|
+
return new Response("Not Found", { status: 404 });
|
|
420
|
+
}
|
|
421
|
+
const locale = context.get(localeKey);
|
|
422
|
+
return createHtmlResponse(renderHomePage(locale));
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
// 3. Start server
|
|
428
|
+
const PORT = Number(process.env.PORT || 3000);
|
|
429
|
+
const server = http.createServer(
|
|
430
|
+
createRequestListener((request) => router.fetch(request))
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
server.listen(PORT, () => {
|
|
434
|
+
console.log(`Server running at http://localhost:${PORT}`);
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
export default {
|
|
438
|
+
port: PORT,
|
|
439
|
+
fetch(request: Request) {
|
|
440
|
+
return router.fetch(request);
|
|
441
|
+
},
|
|
442
|
+
};
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
</Step>
|
|
446
|
+
<Step number={9} title="Audit and Auto-Fill Translations">
|
|
447
|
+
|
|
448
|
+
Intlayer provides a CLI to audit for missing translations and automatically fill them using AI:
|
|
449
|
+
|
|
450
|
+
```bash packageManager="npm"
|
|
451
|
+
# Audit missing translations
|
|
452
|
+
npx intlayer test
|
|
453
|
+
|
|
454
|
+
# Fill missing translations using AI
|
|
455
|
+
npx intlayer fill
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
```bash packageManager="pnpm"
|
|
459
|
+
# Audit missing translations
|
|
460
|
+
pnpm dlx intlayer test
|
|
461
|
+
|
|
462
|
+
# Fill missing translations using AI
|
|
463
|
+
pnpm dlx intlayer fill
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
```bash packageManager="yarn"
|
|
467
|
+
# Audit missing translations
|
|
468
|
+
yarn dlx intlayer test
|
|
469
|
+
|
|
470
|
+
# Fill missing translations using AI
|
|
471
|
+
yarn dlx intlayer fill
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
```bash packageManager="bun"
|
|
475
|
+
# Audit missing translations
|
|
476
|
+
bun x intlayer test
|
|
477
|
+
|
|
478
|
+
# Fill missing translations using AI
|
|
479
|
+
bun x intlayer fill
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
</Step>
|
|
483
|
+
</Steps>
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
## TypeScript Configuration
|
|
488
|
+
|
|
489
|
+
Ensure that your `tsconfig.json` includes the generated `.intlayer` types:
|
|
490
|
+
|
|
491
|
+
```json fileName="tsconfig.json"
|
|
492
|
+
{
|
|
493
|
+
"compilerOptions": {
|
|
494
|
+
"moduleResolution": "Bundler",
|
|
495
|
+
"module": "ESNext",
|
|
496
|
+
"target": "ESNext",
|
|
497
|
+
"skipLibCheck": true,
|
|
498
|
+
"strict": true
|
|
499
|
+
},
|
|
500
|
+
"include": ["src/**/*", ".intlayer/**/*.ts"]
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## Conclusion
|
|
507
|
+
|
|
508
|
+
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.
|
|
@@ -975,7 +975,7 @@ bun add @intlayer/swc --dev
|
|
|
975
975
|
<Tabs>
|
|
976
976
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
977
977
|
|
|
978
|
-
Since
|
|
978
|
+
Since next-intlayer v9.5, `withIntlayer` starts the content watcher itself, no need extra set up.
|
|
979
979
|
|
|
980
980
|
</Tab>
|
|
981
981
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -1275,7 +1275,7 @@ bun run build # Or bun run dev
|
|
|
1275
1275
|
<Tabs>
|
|
1276
1276
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
1277
1277
|
|
|
1278
|
-
Since
|
|
1278
|
+
Since next-intlayer v9.5, `withIntlayer` starts the content watcher itself, no need extra set up.
|
|
1279
1279
|
|
|
1280
1280
|
</Tab>
|
|
1281
1281
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -972,7 +972,7 @@ bun add @intlayer/swc --dev
|
|
|
972
972
|
<Tabs>
|
|
973
973
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
974
974
|
|
|
975
|
-
Desde
|
|
975
|
+
Desde next-intlayer v9.5, `withIntlayer` inicia el content watcher por sí mismo, no se necesita configuración adicional.
|
|
976
976
|
|
|
977
977
|
</Tab>
|
|
978
978
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -1292,7 +1292,7 @@ bun run build # Or bun run dev
|
|
|
1292
1292
|
<Tabs>
|
|
1293
1293
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
1294
1294
|
|
|
1295
|
-
Desde
|
|
1295
|
+
Desde next-intlayer v9.5, `withIntlayer` inicia el content watcher por sí mismo, no se necesita configuración adicional.
|
|
1296
1296
|
|
|
1297
1297
|
</Tab>
|
|
1298
1298
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -972,7 +972,7 @@ bun add @intlayer/swc --dev
|
|
|
972
972
|
<Tabs>
|
|
973
973
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
974
974
|
|
|
975
|
-
Depuis
|
|
975
|
+
Depuis next-intlayer v9.5, `withIntlayer` démarre le content watcher lui-même, aucune configuration supplémentaire n'est nécessaire.
|
|
976
976
|
|
|
977
977
|
</Tab>
|
|
978
978
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -1311,7 +1311,7 @@ bun run build # Or bun run dev
|
|
|
1311
1311
|
<Tabs>
|
|
1312
1312
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
1313
1313
|
|
|
1314
|
-
Depuis
|
|
1314
|
+
Depuis next-intlayer v9.5, `withIntlayer` démarre le content watcher lui-même, aucune configuration supplémentaire n'est nécessaire.
|
|
1315
1315
|
|
|
1316
1316
|
</Tab>
|
|
1317
1317
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|
|
@@ -976,7 +976,7 @@ bun add @intlayer/swc --dev
|
|
|
976
976
|
<Tabs>
|
|
977
977
|
<Tab label='Intlayer >=9.5' value='intlayer>=9.5'>
|
|
978
978
|
|
|
979
|
-
|
|
979
|
+
next-intlayer v9.5 से, `withIntlayer` सामग्री वॉचर (content watcher) को अपने आप शुरू करता है, किसी अतिरिक्त सेटअप की आवश्यकता नहीं है।
|
|
980
980
|
|
|
981
981
|
</Tab>
|
|
982
982
|
<Tab label='Intlayer <9.5' value='intlayer<9.5'>
|