@intlayer/docs 7.5.6 → 7.5.7

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.
Files changed (173) hide show
  1. package/blog/ar/intlayer_with_i18next.md +4 -4
  2. package/blog/ar/intlayer_with_next-i18next.md +4 -4
  3. package/blog/ar/intlayer_with_next-intl.md +4 -4
  4. package/blog/ar/intlayer_with_react-i18next.md +4 -4
  5. package/blog/ar/intlayer_with_react-intl.md +4 -4
  6. package/blog/ar/intlayer_with_vue-i18n.md +4 -4
  7. package/blog/de/intlayer_with_i18next.md +4 -4
  8. package/blog/de/intlayer_with_next-i18next.md +4 -4
  9. package/blog/de/intlayer_with_next-intl.md +4 -4
  10. package/blog/de/intlayer_with_react-i18next.md +4 -4
  11. package/blog/de/intlayer_with_react-intl.md +4 -4
  12. package/blog/de/intlayer_with_vue-i18n.md +4 -4
  13. package/blog/en/intlayer_with_i18next.md +4 -4
  14. package/blog/en/intlayer_with_next-i18next.md +4 -4
  15. package/blog/en/intlayer_with_next-intl.md +4 -4
  16. package/blog/en/intlayer_with_react-i18next.md +4 -4
  17. package/blog/en/intlayer_with_react-intl.md +4 -4
  18. package/blog/en/intlayer_with_vue-i18n.md +4 -4
  19. package/blog/en-GB/intlayer_with_i18next.md +4 -4
  20. package/blog/en-GB/intlayer_with_next-i18next.md +4 -4
  21. package/blog/en-GB/intlayer_with_next-intl.md +4 -4
  22. package/blog/en-GB/intlayer_with_react-i18next.md +4 -4
  23. package/blog/en-GB/intlayer_with_react-intl.md +4 -4
  24. package/blog/en-GB/intlayer_with_vue-i18n.md +4 -4
  25. package/blog/es/intlayer_with_i18next.md +4 -4
  26. package/blog/es/intlayer_with_next-i18next.md +4 -4
  27. package/blog/es/intlayer_with_next-intl.md +4 -4
  28. package/blog/es/intlayer_with_react-i18next.md +4 -4
  29. package/blog/es/intlayer_with_react-intl.md +4 -4
  30. package/blog/es/intlayer_with_vue-i18n.md +4 -4
  31. package/blog/fr/intlayer_with_i18next.md +4 -4
  32. package/blog/fr/intlayer_with_next-i18next.md +4 -4
  33. package/blog/fr/intlayer_with_next-intl.md +4 -4
  34. package/blog/fr/intlayer_with_react-i18next.md +4 -4
  35. package/blog/fr/intlayer_with_react-intl.md +4 -4
  36. package/blog/fr/intlayer_with_vue-i18n.md +4 -4
  37. package/blog/hi/intlayer_with_i18next.md +4 -4
  38. package/blog/hi/intlayer_with_next-i18next.md +4 -4
  39. package/blog/hi/intlayer_with_next-intl.md +4 -4
  40. package/blog/hi/intlayer_with_react-i18next.md +4 -4
  41. package/blog/hi/intlayer_with_react-intl.md +4 -4
  42. package/blog/hi/intlayer_with_vue-i18n.md +4 -4
  43. package/blog/id/intlayer_with_i18next.md +4 -4
  44. package/blog/id/intlayer_with_next-i18next.md +4 -4
  45. package/blog/id/intlayer_with_next-intl.md +4 -4
  46. package/blog/id/intlayer_with_react-i18next.md +4 -4
  47. package/blog/id/intlayer_with_react-intl.md +4 -4
  48. package/blog/id/intlayer_with_vue-i18n.md +4 -4
  49. package/blog/it/intlayer_with_i18next.md +4 -4
  50. package/blog/it/intlayer_with_next-i18next.md +4 -4
  51. package/blog/it/intlayer_with_next-intl.md +4 -4
  52. package/blog/it/intlayer_with_react-i18next.md +4 -4
  53. package/blog/it/intlayer_with_react-intl.md +4 -4
  54. package/blog/it/intlayer_with_vue-i18n.md +4 -4
  55. package/blog/ja/intlayer_with_i18next.md +4 -4
  56. package/blog/ja/intlayer_with_next-i18next.md +4 -4
  57. package/blog/ja/intlayer_with_next-intl.md +4 -4
  58. package/blog/ja/intlayer_with_react-i18next.md +4 -4
  59. package/blog/ja/intlayer_with_react-intl.md +4 -4
  60. package/blog/ja/intlayer_with_vue-i18n.md +4 -4
  61. package/blog/ko/intlayer_with_i18next.md +4 -4
  62. package/blog/ko/intlayer_with_next-i18next.md +4 -4
  63. package/blog/ko/intlayer_with_next-intl.md +4 -4
  64. package/blog/ko/intlayer_with_react-i18next.md +4 -4
  65. package/blog/ko/intlayer_with_react-intl.md +4 -4
  66. package/blog/ko/intlayer_with_vue-i18n.md +4 -4
  67. package/blog/pl/intlayer_with_i18next.md +4 -4
  68. package/blog/pl/intlayer_with_next-i18next.md +4 -4
  69. package/blog/pl/intlayer_with_next-intl.md +4 -4
  70. package/blog/pl/intlayer_with_react-i18next.md +4 -4
  71. package/blog/pl/intlayer_with_react-intl.md +4 -4
  72. package/blog/pl/intlayer_with_vue-i18n.md +4 -4
  73. package/blog/pt/intlayer_with_i18next.md +4 -4
  74. package/blog/pt/intlayer_with_next-i18next.md +4 -4
  75. package/blog/pt/intlayer_with_next-intl.md +4 -4
  76. package/blog/pt/intlayer_with_react-i18next.md +4 -4
  77. package/blog/pt/intlayer_with_react-intl.md +4 -4
  78. package/blog/pt/intlayer_with_vue-i18n.md +4 -4
  79. package/blog/ru/intlayer_with_i18next.md +4 -4
  80. package/blog/ru/intlayer_with_next-i18next.md +4 -4
  81. package/blog/ru/intlayer_with_next-intl.md +4 -4
  82. package/blog/ru/intlayer_with_react-i18next.md +4 -4
  83. package/blog/ru/intlayer_with_react-intl.md +4 -4
  84. package/blog/ru/intlayer_with_vue-i18n.md +4 -4
  85. package/blog/tr/intlayer_with_i18next.md +4 -4
  86. package/blog/tr/intlayer_with_next-i18next.md +4 -4
  87. package/blog/tr/intlayer_with_next-intl.md +4 -4
  88. package/blog/tr/intlayer_with_react-i18next.md +4 -4
  89. package/blog/tr/intlayer_with_react-intl.md +4 -4
  90. package/blog/tr/intlayer_with_vue-i18n.md +4 -4
  91. package/blog/vi/intlayer_with_i18next.md +4 -4
  92. package/blog/vi/intlayer_with_next-i18next.md +4 -4
  93. package/blog/vi/intlayer_with_next-intl.md +4 -4
  94. package/blog/vi/intlayer_with_react-i18next.md +4 -4
  95. package/blog/vi/intlayer_with_react-intl.md +4 -4
  96. package/blog/vi/intlayer_with_vue-i18n.md +4 -4
  97. package/blog/zh/intlayer_with_i18next.md +4 -4
  98. package/blog/zh/intlayer_with_next-i18next.md +4 -4
  99. package/blog/zh/intlayer_with_next-intl.md +4 -4
  100. package/blog/zh/intlayer_with_react-i18next.md +4 -4
  101. package/blog/zh/intlayer_with_react-intl.md +4 -4
  102. package/blog/zh/intlayer_with_vue-i18n.md +4 -4
  103. package/docs/ar/intlayer_with_next-i18next.md +3 -3
  104. package/docs/ar/intlayer_with_next-intl.md +3 -3
  105. package/docs/ar/intlayer_with_react_router_v7.md +72 -16
  106. package/docs/ar/intlayer_with_react_router_v7_fs_routes.md +2 -0
  107. package/docs/de/intlayer_with_next-i18next.md +3 -3
  108. package/docs/de/intlayer_with_next-intl.md +3 -3
  109. package/docs/de/intlayer_with_react_router_v7.md +72 -15
  110. package/docs/de/intlayer_with_react_router_v7_fs_routes.md +95 -19
  111. package/docs/en/configuration.md +1 -0
  112. package/docs/en/intlayer_with_next-i18next.md +3 -3
  113. package/docs/en/intlayer_with_next-intl.md +3 -3
  114. package/docs/en/intlayer_with_react_router_v7.md +74 -15
  115. package/docs/en/intlayer_with_react_router_v7_fs_routes.md +98 -19
  116. package/docs/en-GB/configuration.md +1 -0
  117. package/docs/en-GB/intlayer_with_next-i18next.md +3 -3
  118. package/docs/en-GB/intlayer_with_next-intl.md +3 -3
  119. package/docs/en-GB/intlayer_with_react_router_v7.md +73 -16
  120. package/docs/en-GB/intlayer_with_react_router_v7_fs_routes.md +2 -0
  121. package/docs/es/intlayer_with_next-i18next.md +3 -3
  122. package/docs/es/intlayer_with_next-intl.md +3 -3
  123. package/docs/es/intlayer_with_react_router_v7.md +72 -15
  124. package/docs/es/intlayer_with_react_router_v7_fs_routes.md +95 -19
  125. package/docs/fr/intlayer_with_next-i18next.md +3 -3
  126. package/docs/fr/intlayer_with_next-intl.md +3 -3
  127. package/docs/fr/intlayer_with_react_router_v7.md +72 -15
  128. package/docs/fr/intlayer_with_react_router_v7_fs_routes.md +95 -19
  129. package/docs/hi/intlayer_with_next-i18next.md +3 -3
  130. package/docs/hi/intlayer_with_next-intl.md +3 -3
  131. package/docs/hi/intlayer_with_react_router_v7.md +72 -16
  132. package/docs/hi/intlayer_with_react_router_v7_fs_routes.md +2 -0
  133. package/docs/id/intlayer_with_next-i18next.md +3 -3
  134. package/docs/id/intlayer_with_next-intl.md +3 -3
  135. package/docs/id/intlayer_with_react_router_v7.md +72 -15
  136. package/docs/id/intlayer_with_react_router_v7_fs_routes.md +2 -0
  137. package/docs/it/intlayer_with_next-i18next.md +3 -3
  138. package/docs/it/intlayer_with_next-intl.md +3 -3
  139. package/docs/it/intlayer_with_react_router_v7.md +72 -15
  140. package/docs/it/intlayer_with_react_router_v7_fs_routes.md +95 -19
  141. package/docs/ja/intlayer_with_next-i18next.md +3 -3
  142. package/docs/ja/intlayer_with_next-intl.md +3 -3
  143. package/docs/ja/intlayer_with_react_router_v7.md +72 -15
  144. package/docs/ja/intlayer_with_react_router_v7_fs_routes.md +95 -19
  145. package/docs/ko/intlayer_with_next-i18next.md +3 -3
  146. package/docs/ko/intlayer_with_next-intl.md +3 -3
  147. package/docs/ko/intlayer_with_react_router_v7.md +72 -15
  148. package/docs/ko/intlayer_with_react_router_v7_fs_routes.md +2 -0
  149. package/docs/pl/intlayer_with_next-i18next.md +3 -3
  150. package/docs/pl/intlayer_with_next-intl.md +3 -3
  151. package/docs/pl/intlayer_with_react_router_v7.md +45 -13
  152. package/docs/pl/intlayer_with_react_router_v7_fs_routes.md +94 -18
  153. package/docs/pt/intlayer_with_next-i18next.md +3 -3
  154. package/docs/pt/intlayer_with_next-intl.md +3 -3
  155. package/docs/pt/intlayer_with_react_router_v7.md +79 -46
  156. package/docs/pt/intlayer_with_react_router_v7_fs_routes.md +95 -19
  157. package/docs/ru/intlayer_with_next-i18next.md +3 -3
  158. package/docs/ru/intlayer_with_next-intl.md +3 -3
  159. package/docs/ru/intlayer_with_react_router_v7.md +72 -15
  160. package/docs/ru/intlayer_with_react_router_v7_fs_routes.md +95 -19
  161. package/docs/tr/intlayer_with_next-i18next.md +3 -3
  162. package/docs/tr/intlayer_with_next-intl.md +3 -3
  163. package/docs/tr/intlayer_with_react_router_v7.md +72 -15
  164. package/docs/tr/intlayer_with_react_router_v7_fs_routes.md +95 -19
  165. package/docs/vi/intlayer_with_next-i18next.md +3 -3
  166. package/docs/vi/intlayer_with_next-intl.md +3 -3
  167. package/docs/vi/intlayer_with_react_router_v7.md +72 -15
  168. package/docs/vi/intlayer_with_react_router_v7_fs_routes.md +2 -0
  169. package/docs/zh/intlayer_with_next-i18next.md +3 -3
  170. package/docs/zh/intlayer_with_next-intl.md +3 -3
  171. package/docs/zh/intlayer_with_react_router_v7.md +72 -15
  172. package/docs/zh/intlayer_with_react_router_v7_fs_routes.md +2 -0
  173. package/package.json +6 -6
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  createdAt: 2025-09-04
3
- updatedAt: 2025-10-03
3
+ updatedAt: 2025-12-27
4
4
  title: كيفية ترجمة تطبيق React Router v7 – دليل i18n 2025
5
5
  description: تعلّم كيفية إضافة التدويل (i18n) إلى تطبيق React Router v7 الخاص بك باستخدام Intlayer. اتبع هذا الدليل الشامل لجعل تطبيقك متعدد اللغات مع توجيه يدعم اللغة المحلية.
6
6
  keywords:
@@ -20,6 +20,9 @@ slugs:
20
20
  applicationTemplate: https://github.com/aymericzip/intlayer-react-router-v7-template
21
21
  youtubeVideo: https://www.youtube.com/watch?v=dS9L7uJeak4
22
22
  history:
23
+ - version: 7.5.6
24
+ date: 2025-12-27
25
+ changes: تحديث التخطيط ومعالجة 404
23
26
  - version: 6.1.5
24
27
  date: 2025-10-03
25
28
  changes: تحديث الوثيقة
@@ -168,14 +171,11 @@ export default defineConfig({
168
171
  قم بإعداد تكوين التوجيه الخاص بك مع مسارات مدركة للغة:
169
172
 
170
173
  ```typescript fileName="app/routes.ts"
171
- typescript fileName="app/routes.ts"
172
174
  import { layout, route, type RouteConfig } from "@react-router/dev/routes";
173
175
 
174
176
  export default [
175
- layout("routes/layout.tsx", [
176
- route("/:lang?", "routes/page.tsx"), // الصفحة الرئيسية المحلية
177
- route("/:lang?/about", "routes/about/page.tsx"), // صفحة حول المحلية
178
- ]),
177
+ route("/:lang?", "routes/page.tsx"), // الصفحة الرئيسية المحلية
178
+ route("/:lang?/about", "routes/about/page.tsx"), // صفحة حول المحلية
179
179
  ] satisfies RouteConfig;
180
180
  ```
181
181
 
@@ -185,19 +185,50 @@ export default [
185
185
 
186
186
  #### التخطيط الجذري
187
187
 
188
- ```tsx fileName="app/routes/layout.tsx"
188
+ ```tsx fileName="app/root.tsx"
189
+ import { getLocaleFromPath } from "intlayer";
189
190
  import { IntlayerProvider } from "react-intlayer";
190
- import { Outlet } from "react-router";
191
+ import {
192
+ data,
193
+ Meta,
194
+ Scripts,
195
+ ScrollRestoration,
196
+ useLoaderData,
197
+ } from "react-router";
198
+ import type { Route } from "./+types/root";
191
199
 
192
- import type { Route } from "./+types/layout";
200
+ // ... Unchanged App, links and ErrorBoundary code
193
201
 
194
- export default function RootLayout({ params }: Route.ComponentProps) {
195
- const { locale } = params;
202
+ export async function loader({ request }: Route.LoaderArgs) {
203
+ const locale = getLocaleFromPath(request.url);
204
+
205
+ if (!locale) {
206
+ throw data("Language not supported", { status: 404 });
207
+ }
208
+
209
+ return { locale };
210
+ }
211
+
212
+ export function Layout({
213
+ children,
214
+ }: { children: React.ReactNode } & Route.ComponentProps) {
215
+ const data = useLoaderData<typeof loader>();
216
+ const { locale } = data ?? {};
196
217
 
197
218
  return (
198
- <IntlayerProvider locale={locale}>
199
- <Outlet />
200
- </IntlayerProvider>
219
+ <html lang={locale}>
220
+ <head>
221
+ <meta charSet="utf-8" />
222
+ <meta content="width=device-width, initial-scale=1" name="viewport" />
223
+ <Meta />
224
+ <Links />
225
+ </head>
226
+ <body>
227
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
228
+ <ScrollRestoration />
229
+ <Scripts />
230
+ </body>
231
+ </html>
201
232
  );
202
233
  }
203
234
  ```
@@ -311,9 +342,34 @@ export const useLocalizedNavigate = () => {
311
342
 
312
343
  #### الصفحة الرئيسية المترجمة
313
344
 
314
- ```tsx fileName="app/routes/[lang]/page.tsx"
345
+ ```tsx fileName="app/routes/page.tsx"
346
+ import { getIntlayer, validatePrefix } from "intlayer";
315
347
  import { useIntlayer } from "react-intlayer";
316
- import { LocalizedLink } from "~/components/localized-link";
348
+ import { data } from "react-router";
349
+
350
+ import { LocaleSwitcher } from "~/components/locale-switcher";
351
+
352
+ import { Navbar } from "~/components/navbar";
353
+ import type { Route } from "./+types/page";
354
+
355
+ export const loader = ({ params }: Route.LoaderArgs) => {
356
+ const { locale } = params;
357
+
358
+ const { isValid } = validatePrefix(locale);
359
+
360
+ if (!isValid) {
361
+ throw data("Locale not supported", { status: 404 });
362
+ }
363
+ };
364
+
365
+ export const meta: Route.MetaFunction = ({ params }) => {
366
+ const content = getIntlayer("page", params.locale);
367
+
368
+ return [
369
+ { title: content.title },
370
+ { content: content.description, name: "description" },
371
+ ];
372
+ };
317
373
 
318
374
  export default function Page() {
319
375
  const { title, description, aboutLink } = useIntlayer("page");
@@ -32,6 +32,8 @@ history:
32
32
 
33
33
  يوضح هذا الدليل كيفية دمج **Intlayer** لتحقيق التدويل السلس في مشاريع React Router v7 مع توجيه يدعم اللغة المحلية، ودعم TypeScript، وممارسات تطوير حديثة.
34
34
 
35
+ للحصول على التوجيه من جانب العميل، راجع دليل [Intlayer مع React Router v7](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ar/intlayer_with_react_router_v7.md).
36
+
35
37
  ## Table of Contents
36
38
 
37
39
  <TOC/>
@@ -552,15 +552,15 @@ Intlayer hilft Ihnen, JSON-Übersetzungen synchron zu halten, auf fehlende Schl
552
552
  Installieren Sie die Intlayer-Abhängigkeiten:
553
553
 
554
554
  ```bash packageManager="npm"
555
- npm install intlayer @intlayer/sync-json-plugin -D
555
+ npm install intlayer @intlayer/sync-json-plugin --save-dev
556
556
  ```
557
557
 
558
558
  ```bash packageManager="pnpm"
559
- pnpm add intlayer @intlayer/sync-json-plugin -D
559
+ pnpm add intlayer @intlayer/sync-json-plugin --save-dev
560
560
  ```
561
561
 
562
562
  ```bash packageManager="yarn"
563
- yarn add intlayer @intlayer/sync-json-plugin -D
563
+ yarn add intlayer @intlayer/sync-json-plugin --dev
564
564
  ```
565
565
 
566
566
  ```ts fileName="intlayer.config.ts"
@@ -391,15 +391,15 @@ export const config = {
391
391
  Installieren Sie die Intlayer-Abhängigkeiten:
392
392
 
393
393
  ```bash packageManager="npm"
394
- npm install intlayer @intlayer/sync-json-plugin -D
394
+ npm install intlayer @intlayer/sync-json-plugin --save-dev
395
395
  ```
396
396
 
397
397
  ```bash packageManager="yarn"
398
- yarn add intlayer @intlayer/sync-json-plugin -D
398
+ yarn add intlayer @intlayer/sync-json-plugin --dev
399
399
  ```
400
400
 
401
401
  ```bash packageManager="pnpm"
402
- pnpm add intlayer @intlayer/sync-json-plugin -D
402
+ pnpm add intlayer @intlayer/sync-json-plugin --save-dev
403
403
  ```
404
404
 
405
405
  Erstellen Sie die Intlayer-Konfigurationsdatei:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  createdAt: 2025-09-04
3
- updatedAt: 2025-10-03
3
+ updatedAt: 2025-12-27
4
4
  title: Wie Sie Ihre React Router v7 übersetzen – i18n-Leitfaden 2025
5
5
  description: Erfahren Sie, wie Sie Internationalisierung (i18n) zu Ihrer React Router v7-Anwendung mit Intlayer hinzufügen. Folgen Sie dieser umfassenden Anleitung, um Ihre App mehrsprachig mit lokalisierungsbewusstem Routing zu machen.
6
6
  keywords:
@@ -20,6 +20,9 @@ slugs:
20
20
  applicationTemplate: https://github.com/aymericzip/intlayer-react-router-v7-template
21
21
  youtubeVideo: https://www.youtube.com/watch?v=dS9L7uJeak4
22
22
  history:
23
+ - version: 7.5.6
24
+ date: 2025-12-27
25
+ changes: Layout aktualisieren und 404 behandeln
23
26
  - version: 6.1.5
24
27
  date: 2025-10-03
25
28
  changes: Dokumentation aktualisiert
@@ -173,10 +176,8 @@ Richten Sie Ihre Routing-Konfiguration mit sprachsensitiven Routen ein:
173
176
  import { layout, route, type RouteConfig } from "@react-router/dev/routes";
174
177
 
175
178
  export default [
176
- layout("routes/layout.tsx", [
177
- route("/:lang?", "routes/page.tsx"), // Lokalisierte Startseite
178
- route("/:lang?/about", "routes/about/page.tsx"), // Lokalisierte Über-Seite
179
- ]),
179
+ route("/:lang?", "routes/page.tsx"), // Lokalisierte Startseite
180
+ route("/:lang?/about", "routes/about/page.tsx"), // Lokalisierte Über-Seite
180
181
  ] satisfies RouteConfig;
181
182
  ```
182
183
 
@@ -186,19 +187,50 @@ Richten Sie Ihr Root-Layout und sprachspezifische Layouts ein:
186
187
 
187
188
  #### Root-Layout
188
189
 
189
- ```tsx fileName="app/routes/layout.tsx"
190
+ ```tsx fileName="app/root.tsx"
191
+ import { getLocaleFromPath } from "intlayer";
190
192
  import { IntlayerProvider } from "react-intlayer";
191
- import { Outlet } from "react-router";
193
+ import {
194
+ data,
195
+ Meta,
196
+ Scripts,
197
+ ScrollRestoration,
198
+ useLoaderData,
199
+ } from "react-router";
200
+ import type { Route } from "./+types/root";
192
201
 
193
- import type { Route } from "./+types/layout";
202
+ // ... Unchanged App, links and ErrorBoundary code
194
203
 
195
- export default function RootLayout({ params }: Route.ComponentProps) {
196
- const { locale } = params;
204
+ export async function loader({ request }: Route.LoaderArgs) {
205
+ const locale = getLocaleFromPath(request.url);
206
+
207
+ if (!locale) {
208
+ throw data("Language not supported", { status: 404 });
209
+ }
210
+
211
+ return { locale };
212
+ }
213
+
214
+ export function Layout({
215
+ children,
216
+ }: { children: React.ReactNode } & Route.ComponentProps) {
217
+ const data = useLoaderData<typeof loader>();
218
+ const { locale } = data ?? {};
197
219
 
198
220
  return (
199
- <IntlayerProvider locale={locale}>
200
- <Outlet />
201
- </IntlayerProvider>
221
+ <html lang={locale}>
222
+ <head>
223
+ <meta charSet="utf-8" />
224
+ <meta content="width=device-width, initial-scale=1" name="viewport" />
225
+ <Meta />
226
+ <Links />
227
+ </head>
228
+ <body>
229
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
230
+ <ScrollRestoration />
231
+ <Scripts />
232
+ </body>
233
+ </html>
202
234
  );
203
235
  }
204
236
  ```
@@ -312,9 +344,34 @@ Greifen Sie in Ihrer gesamten Anwendung auf Ihre Inhaltswörterbücher zu:
312
344
 
313
345
  #### Lokalisierte Startseite
314
346
 
315
- ```tsx fileName="app/routes/[lang]/page.tsx"
347
+ ```tsx fileName="app/routes/page.tsx"
348
+ import { getIntlayer, validatePrefix } from "intlayer";
316
349
  import { useIntlayer } from "react-intlayer";
317
- import { LocalizedLink } from "~/components/localized-link";
350
+ import { data } from "react-router";
351
+
352
+ import { LocaleSwitcher } from "~/components/locale-switcher";
353
+
354
+ import { Navbar } from "~/components/navbar";
355
+ import type { Route } from "./+types/page";
356
+
357
+ export const loader = ({ params }: Route.LoaderArgs) => {
358
+ const { locale } = params;
359
+
360
+ const { isValid } = validatePrefix(locale);
361
+
362
+ if (!isValid) {
363
+ throw data("Locale not supported", { status: 404 });
364
+ }
365
+ };
366
+
367
+ export const meta: Route.MetaFunction = ({ params }) => {
368
+ const content = getIntlayer("page", params.locale);
369
+
370
+ return [
371
+ { title: content.title },
372
+ { content: content.description, name: "description" },
373
+ ];
374
+ };
318
375
 
319
376
  export default function Page() {
320
377
  const { title, description, aboutLink } = useIntlayer("page");
@@ -31,6 +31,8 @@ history:
31
31
 
32
32
  Diese Anleitung zeigt, wie Sie **Intlayer** für nahtlose Internationalisierung in React Router v7-Projekten mit **dateisystembasiertem Routing** (`@react-router/fs-routes`) mit lokalisierungsbewusstem Routing, TypeScript-Unterstützung und modernen Entwicklungsmethoden integrieren.
33
33
 
34
+ Für clientseitiges Routing lesen Sie bitte die Anleitung [Intlayer mit React Router v7](https://github.com/aymericzip/intlayer/blob/main/docs/docs/de/intlayer_with_react_router_v7.md).
35
+
34
36
  ## Table of Contents
35
37
 
36
38
  <TOC/>
@@ -197,12 +199,13 @@ Erstellen Sie die folgenden Dateien in Ihrem Verzeichnis `app/routes/`:
197
199
  #### Dateistruktur
198
200
 
199
201
  ```bash
200
- app/routes/
201
- ├── ($locale)._layout.tsx # Layout-Wrapper für Locale-Routen
202
- ├── ($locale)._index.tsx # Startseite (/:locale?)
203
- ├── ($locale)._index.content.ts # Startseiten-Inhalt
204
- ├── ($locale).about.tsx # Über-Seite (/:locale?/about)
205
- └── ($locale).about.content.ts # Über-Seiten-Inhalt
202
+ app/
203
+ ├── root.tsx # Layout-Wrapper für Locale-Routen
204
+ └──routes/
205
+ ├── ($locale)._index.tsx # Startseite (/, /es, etc.)
206
+ ├── ($locale)._index.content.ts # Startseiten-Inhalt
207
+ ├── ($locale).about.tsx # Über-Seite (/about, /es/about, etc.)
208
+ └── ($locale).about.content.ts # Über-Seiten-Inhalt
206
209
  ```
207
210
 
208
211
  Die Namenskonventionen:
@@ -214,23 +217,50 @@ Die Namenskonventionen:
214
217
 
215
218
  #### Layout-Komponente
216
219
 
217
- ```tsx fileName="app/routes/($locale)._layout.tsx"
220
+ ```tsx fileName="app/root.tsx"
221
+ import { getLocaleFromPath } from "intlayer";
218
222
  import { IntlayerProvider } from "react-intlayer";
219
- import { Outlet } from "react-router";
223
+ import {
224
+ isRouteErrorResponse,
225
+ Meta,
226
+ Outlet,
227
+ Scripts,
228
+ ScrollRestoration,
229
+ useLoaderData,
230
+ } from "react-router";
220
231
 
221
- import { useI18nHTMLAttributes } from "~/hooks/useI18nHTMLAttributes";
232
+ import type { Route } from "./+types/root";
222
233
 
223
- import type { Route } from "./+types/($locale)._layout";
234
+ import "./app.css";
224
235
 
225
- export default function RootLayout({ params }: Route.ComponentProps) {
226
- useI18nHTMLAttributes();
236
+ // links and ErrorBoundary code
227
237
 
228
- const { locale } = params;
238
+ export async function loader({ request }: Route.LoaderArgs) {
239
+ const locale = getLocaleFromPath(request.url);
240
+
241
+ return { locale };
242
+ }
243
+
244
+ export function Layout({
245
+ children,
246
+ }: { children: React.ReactNode } & Route.ComponentProps) {
247
+ const data = useLoaderData<typeof loader>();
248
+ const { locale } = data ?? {};
229
249
 
230
250
  return (
231
- <IntlayerProvider locale={locale}>
232
- <Outlet />
233
- </IntlayerProvider>
251
+ <html lang={locale}>
252
+ <head>
253
+ <meta charSet="utf-8" />
254
+ <meta content="width=device-width, initial-scale=1" name="viewport" />
255
+ <Meta />
256
+ <Links />
257
+ </head>
258
+ <body>
259
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
260
+ <ScrollRestoration />
261
+ <Scripts />
262
+ </body>
263
+ </html>
234
264
  );
235
265
  }
236
266
  ```
@@ -238,11 +268,34 @@ export default function RootLayout({ params }: Route.ComponentProps) {
238
268
  #### Index-Seite
239
269
 
240
270
  ```tsx fileName="app/routes/($locale)._index.tsx"
271
+ import { getIntlayer, validatePrefix } from "intlayer";
241
272
  import { useIntlayer } from "react-intlayer";
242
- import { LocalizedLink } from "~/components/localized-link";
273
+ import { data } from "react-router";
274
+
275
+ import { LocaleSwitcher } from "~/components/locale-switcher";
276
+ import { Navbar } from "~/components/navbar";
243
277
 
244
278
  import type { Route } from "./+types/($locale)._index";
245
279
 
280
+ export const loader = ({ params }: Route.LoaderArgs) => {
281
+ const { locale } = params;
282
+
283
+ const { isValid } = validatePrefix(locale);
284
+
285
+ if (!isValid) {
286
+ throw data("Locale not supported", { status: 404 });
287
+ }
288
+ };
289
+
290
+ export const meta: Route.MetaFunction = ({ params }) => {
291
+ const content = getIntlayer("page", params.locale);
292
+
293
+ return [
294
+ { title: content.title },
295
+ { content: content.description, name: "description" },
296
+ ];
297
+ };
298
+
246
299
  export default function Page() {
247
300
  const { title, description, aboutLink } = useIntlayer("page");
248
301
 
@@ -261,11 +314,34 @@ export default function Page() {
261
314
  #### Über-Seite
262
315
 
263
316
  ```tsx fileName="app/routes/($locale).about.tsx"
317
+ import { getIntlayer, validatePrefix } from "intlayer";
264
318
  import { useIntlayer } from "react-intlayer";
265
- import { LocalizedLink } from "~/components/localized-link";
319
+ import { data } from "react-router";
320
+
321
+ import { LocaleSwitcher } from "~/components/locale-switcher";
322
+ import { Navbar } from "~/components/navbar";
266
323
 
267
324
  import type { Route } from "./+types/($locale).about";
268
325
 
326
+ export const loader = ({ params }: Route.LoaderArgs) => {
327
+ const { locale } = params;
328
+
329
+ const { isValid } = validatePrefix(locale);
330
+
331
+ if (!isValid) {
332
+ throw data("Locale not supported", { status: 404 });
333
+ }
334
+ };
335
+
336
+ export const meta: Route.MetaFunction = ({ params }) => {
337
+ const content = getIntlayer("about", params.locale);
338
+
339
+ return [
340
+ { title: content.title },
341
+ { content: content.description, name: "description" },
342
+ ];
343
+ };
344
+
269
345
  export default function AboutPage() {
270
346
  const { title, content, homeLink } = useIntlayer("about");
271
347
 
@@ -486,7 +562,7 @@ export const useI18nHTMLAttributes = () => {
486
562
  };
487
563
  ```
488
564
 
489
- Dieser Hook wird bereits in der Layout-Komponente (`($locale)._layout.tsx`) verwendet, die in Schritt 5 gezeigt wird.
565
+ Dieser Hook wird bereits in der Layout-Komponente (`root.tsx`) verwendet, die in Schritt 5 gezeigt wird.
490
566
 
491
567
  ### Schritt 10: Middleware hinzufügen (Optional)
492
568
 
@@ -621,6 +621,7 @@ Intlayer supports multiple AI providers for enhanced flexibility and choice. Cur
621
621
  - **DeepSeek**
622
622
  - **Google Gemini**
623
623
  - **Meta Llama**
624
+ - **ollama**
624
625
 
625
626
  #### Properties
626
627
 
@@ -552,15 +552,15 @@ Intlayer helps you keep JSON translations in sync, test for missing keys, and fi
552
552
  Install the intlayer dependencies:
553
553
 
554
554
  ```bash packageManager="npm"
555
- npm install intlayer @intlayer/sync-json-plugin -D
555
+ npm install intlayer @intlayer/sync-json-plugin --save-dev
556
556
  ```
557
557
 
558
558
  ```bash packageManager="pnpm"
559
- pnpm add intlayer @intlayer/sync-json-plugin -D
559
+ pnpm add intlayer @intlayer/sync-json-plugin --save-dev
560
560
  ```
561
561
 
562
562
  ```bash packageManager="yarn"
563
- yarn add intlayer @intlayer/sync-json-plugin -D
563
+ yarn add intlayer @intlayer/sync-json-plugin --dev
564
564
  ```
565
565
 
566
566
  ```ts fileName="intlayer.config.ts"
@@ -391,15 +391,15 @@ export const config = {
391
391
  Install the intlayer dependencies:
392
392
 
393
393
  ```bash packageManager="npm"
394
- npm install intlayer @intlayer/sync-json-plugin -D
394
+ npm install intlayer @intlayer/sync-json-plugin --save-dev
395
395
  ```
396
396
 
397
397
  ```bash packageManager="yarn"
398
- yarn add intlayer @intlayer/sync-json-plugin -D
398
+ yarn add intlayer @intlayer/sync-json-plugin --dev
399
399
  ```
400
400
 
401
401
  ```bash packageManager="pnpm"
402
- pnpm add intlayer @intlayer/sync-json-plugin -D
402
+ pnpm add intlayer @intlayer/sync-json-plugin --save-dev
403
403
  ```
404
404
 
405
405
  Create the intlayer configuration file:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  createdAt: 2025-09-04
3
- updatedAt: 2025-10-03
3
+ updatedAt: 2025-12-27
4
4
  title: How to translate your React Router v7 app – i18n guide 2025
5
5
  description: Learn how to add internationalization (i18n) to your React Router v7 application using Intlayer. Follow this comprehensive guide to make your app multilingual with locale-aware routing.
6
6
  keywords:
@@ -20,6 +20,9 @@ slugs:
20
20
  applicationTemplate: https://github.com/aymericzip/intlayer-react-router-v7-template
21
21
  youtubeVideo: https://www.youtube.com/watch?v=dS9L7uJeak4
22
22
  history:
23
+ - version: 7.5.6
24
+ date: 2025-12-27
25
+ changes: Update Layout and handle 404
23
26
  - version: 6.1.5
24
27
  date: 2025-10-03
25
28
  changes: Updated doc
@@ -32,6 +35,8 @@ history:
32
35
 
33
36
  This guide demonstrates how to integrate **Intlayer** for seamless internationalization in React Router v7 projects with locale-aware routing, TypeScript support, and modern development practices.
34
37
 
38
+ This guide focuses on frontend routing. For fs-routes routing, refer to the [Intlayer with React Router v7 File-System Routes](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_with_react_router_v7_fs_routes.md) guide.
39
+
35
40
  ## Table of Contents
36
41
 
37
42
  <TOC/>
@@ -179,10 +184,8 @@ Set up your routing configuration with locale-aware routes:
179
184
  import { layout, route, type RouteConfig } from "@react-router/dev/routes";
180
185
 
181
186
  export default [
182
- layout("routes/layout.tsx", [
183
- route("/:lang?", "routes/page.tsx"), // Localized home page
184
- route("/:lang?/about", "routes/about/page.tsx"), // Localized about page
185
- ]),
187
+ route("/:lang?", "routes/page.tsx"), // Localized home page
188
+ route("/:lang?/about", "routes/about/page.tsx"), // Localized about page
186
189
  ] satisfies RouteConfig;
187
190
  ```
188
191
 
@@ -192,19 +195,50 @@ Set up your root layout and locale-specific layouts:
192
195
 
193
196
  #### Root Layout
194
197
 
195
- ```tsx fileName="app/routes/layout.tsx"
198
+ ```tsx fileName="app/root.tsx"
199
+ import { getLocaleFromPath } from "intlayer";
196
200
  import { IntlayerProvider } from "react-intlayer";
197
- import { Outlet } from "react-router";
201
+ import {
202
+ data,
203
+ Meta,
204
+ Scripts,
205
+ ScrollRestoration,
206
+ useLoaderData,
207
+ } from "react-router";
208
+ import type { Route } from "./+types/root";
198
209
 
199
- import type { Route } from "./+types/layout";
210
+ // ... Unchanged App, links and ErrorBoundary code
200
211
 
201
- export default function RootLayout({ params }: Route.ComponentProps) {
202
- const { locale } = params;
212
+ export async function loader({ request }: Route.LoaderArgs) {
213
+ const locale = getLocaleFromPath(request.url);
214
+
215
+ if (!locale) {
216
+ throw data("Language not supported", { status: 404 });
217
+ }
218
+
219
+ return { locale };
220
+ }
221
+
222
+ export function Layout({
223
+ children,
224
+ }: { children: React.ReactNode } & Route.ComponentProps) {
225
+ const data = useLoaderData<typeof loader>();
226
+ const { locale } = data ?? {};
203
227
 
204
228
  return (
205
- <IntlayerProvider locale={locale}>
206
- <Outlet />
207
- </IntlayerProvider>
229
+ <html lang={locale}>
230
+ <head>
231
+ <meta charSet="utf-8" />
232
+ <meta content="width=device-width, initial-scale=1" name="viewport" />
233
+ <Meta />
234
+ <Links />
235
+ </head>
236
+ <body>
237
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
238
+ <ScrollRestoration />
239
+ <Scripts />
240
+ </body>
241
+ </html>
208
242
  );
209
243
  }
210
244
  ```
@@ -316,9 +350,34 @@ Access your content dictionaries throughout your application:
316
350
 
317
351
  #### Localized Home Page
318
352
 
319
- ```tsx fileName="app/routes/[lang]/page.tsx"
353
+ ```tsx fileName="app/routes/page.tsx"
354
+ import { getIntlayer, validatePrefix } from "intlayer";
320
355
  import { useIntlayer } from "react-intlayer";
321
- import { LocalizedLink } from "~/components/localized-link";
356
+ import { data } from "react-router";
357
+
358
+ import { LocaleSwitcher } from "~/components/locale-switcher";
359
+
360
+ import { Navbar } from "~/components/navbar";
361
+ import type { Route } from "./+types/page";
362
+
363
+ export const loader = ({ params }: Route.LoaderArgs) => {
364
+ const { locale } = params;
365
+
366
+ const { isValid } = validatePrefix(locale);
367
+
368
+ if (!isValid) {
369
+ throw data("Locale not supported", { status: 404 });
370
+ }
371
+ };
372
+
373
+ export const meta: Route.MetaFunction = ({ params }) => {
374
+ const content = getIntlayer("page", params.locale);
375
+
376
+ return [
377
+ { title: content.title },
378
+ { content: content.description, name: "description" },
379
+ ];
380
+ };
322
381
 
323
382
  export default function Page() {
324
383
  const { title, description, aboutLink } = useIntlayer("page");