@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.
- package/blog/ar/intlayer_with_i18next.md +4 -4
- package/blog/ar/intlayer_with_next-i18next.md +4 -4
- package/blog/ar/intlayer_with_next-intl.md +4 -4
- package/blog/ar/intlayer_with_react-i18next.md +4 -4
- package/blog/ar/intlayer_with_react-intl.md +4 -4
- package/blog/ar/intlayer_with_vue-i18n.md +4 -4
- package/blog/de/intlayer_with_i18next.md +4 -4
- package/blog/de/intlayer_with_next-i18next.md +4 -4
- package/blog/de/intlayer_with_next-intl.md +4 -4
- package/blog/de/intlayer_with_react-i18next.md +4 -4
- package/blog/de/intlayer_with_react-intl.md +4 -4
- package/blog/de/intlayer_with_vue-i18n.md +4 -4
- package/blog/en/intlayer_with_i18next.md +4 -4
- package/blog/en/intlayer_with_next-i18next.md +4 -4
- package/blog/en/intlayer_with_next-intl.md +4 -4
- package/blog/en/intlayer_with_react-i18next.md +4 -4
- package/blog/en/intlayer_with_react-intl.md +4 -4
- package/blog/en/intlayer_with_vue-i18n.md +4 -4
- package/blog/en-GB/intlayer_with_i18next.md +4 -4
- package/blog/en-GB/intlayer_with_next-i18next.md +4 -4
- package/blog/en-GB/intlayer_with_next-intl.md +4 -4
- package/blog/en-GB/intlayer_with_react-i18next.md +4 -4
- package/blog/en-GB/intlayer_with_react-intl.md +4 -4
- package/blog/en-GB/intlayer_with_vue-i18n.md +4 -4
- package/blog/es/intlayer_with_i18next.md +4 -4
- package/blog/es/intlayer_with_next-i18next.md +4 -4
- package/blog/es/intlayer_with_next-intl.md +4 -4
- package/blog/es/intlayer_with_react-i18next.md +4 -4
- package/blog/es/intlayer_with_react-intl.md +4 -4
- package/blog/es/intlayer_with_vue-i18n.md +4 -4
- package/blog/fr/intlayer_with_i18next.md +4 -4
- package/blog/fr/intlayer_with_next-i18next.md +4 -4
- package/blog/fr/intlayer_with_next-intl.md +4 -4
- package/blog/fr/intlayer_with_react-i18next.md +4 -4
- package/blog/fr/intlayer_with_react-intl.md +4 -4
- package/blog/fr/intlayer_with_vue-i18n.md +4 -4
- package/blog/hi/intlayer_with_i18next.md +4 -4
- package/blog/hi/intlayer_with_next-i18next.md +4 -4
- package/blog/hi/intlayer_with_next-intl.md +4 -4
- package/blog/hi/intlayer_with_react-i18next.md +4 -4
- package/blog/hi/intlayer_with_react-intl.md +4 -4
- package/blog/hi/intlayer_with_vue-i18n.md +4 -4
- package/blog/id/intlayer_with_i18next.md +4 -4
- package/blog/id/intlayer_with_next-i18next.md +4 -4
- package/blog/id/intlayer_with_next-intl.md +4 -4
- package/blog/id/intlayer_with_react-i18next.md +4 -4
- package/blog/id/intlayer_with_react-intl.md +4 -4
- package/blog/id/intlayer_with_vue-i18n.md +4 -4
- package/blog/it/intlayer_with_i18next.md +4 -4
- package/blog/it/intlayer_with_next-i18next.md +4 -4
- package/blog/it/intlayer_with_next-intl.md +4 -4
- package/blog/it/intlayer_with_react-i18next.md +4 -4
- package/blog/it/intlayer_with_react-intl.md +4 -4
- package/blog/it/intlayer_with_vue-i18n.md +4 -4
- package/blog/ja/intlayer_with_i18next.md +4 -4
- package/blog/ja/intlayer_with_next-i18next.md +4 -4
- package/blog/ja/intlayer_with_next-intl.md +4 -4
- package/blog/ja/intlayer_with_react-i18next.md +4 -4
- package/blog/ja/intlayer_with_react-intl.md +4 -4
- package/blog/ja/intlayer_with_vue-i18n.md +4 -4
- package/blog/ko/intlayer_with_i18next.md +4 -4
- package/blog/ko/intlayer_with_next-i18next.md +4 -4
- package/blog/ko/intlayer_with_next-intl.md +4 -4
- package/blog/ko/intlayer_with_react-i18next.md +4 -4
- package/blog/ko/intlayer_with_react-intl.md +4 -4
- package/blog/ko/intlayer_with_vue-i18n.md +4 -4
- package/blog/pl/intlayer_with_i18next.md +4 -4
- package/blog/pl/intlayer_with_next-i18next.md +4 -4
- package/blog/pl/intlayer_with_next-intl.md +4 -4
- package/blog/pl/intlayer_with_react-i18next.md +4 -4
- package/blog/pl/intlayer_with_react-intl.md +4 -4
- package/blog/pl/intlayer_with_vue-i18n.md +4 -4
- package/blog/pt/intlayer_with_i18next.md +4 -4
- package/blog/pt/intlayer_with_next-i18next.md +4 -4
- package/blog/pt/intlayer_with_next-intl.md +4 -4
- package/blog/pt/intlayer_with_react-i18next.md +4 -4
- package/blog/pt/intlayer_with_react-intl.md +4 -4
- package/blog/pt/intlayer_with_vue-i18n.md +4 -4
- package/blog/ru/intlayer_with_i18next.md +4 -4
- package/blog/ru/intlayer_with_next-i18next.md +4 -4
- package/blog/ru/intlayer_with_next-intl.md +4 -4
- package/blog/ru/intlayer_with_react-i18next.md +4 -4
- package/blog/ru/intlayer_with_react-intl.md +4 -4
- package/blog/ru/intlayer_with_vue-i18n.md +4 -4
- package/blog/tr/intlayer_with_i18next.md +4 -4
- package/blog/tr/intlayer_with_next-i18next.md +4 -4
- package/blog/tr/intlayer_with_next-intl.md +4 -4
- package/blog/tr/intlayer_with_react-i18next.md +4 -4
- package/blog/tr/intlayer_with_react-intl.md +4 -4
- package/blog/tr/intlayer_with_vue-i18n.md +4 -4
- package/blog/vi/intlayer_with_i18next.md +4 -4
- package/blog/vi/intlayer_with_next-i18next.md +4 -4
- package/blog/vi/intlayer_with_next-intl.md +4 -4
- package/blog/vi/intlayer_with_react-i18next.md +4 -4
- package/blog/vi/intlayer_with_react-intl.md +4 -4
- package/blog/vi/intlayer_with_vue-i18n.md +4 -4
- package/blog/zh/intlayer_with_i18next.md +4 -4
- package/blog/zh/intlayer_with_next-i18next.md +4 -4
- package/blog/zh/intlayer_with_next-intl.md +4 -4
- package/blog/zh/intlayer_with_react-i18next.md +4 -4
- package/blog/zh/intlayer_with_react-intl.md +4 -4
- package/blog/zh/intlayer_with_vue-i18n.md +4 -4
- package/docs/ar/intlayer_with_next-i18next.md +3 -3
- package/docs/ar/intlayer_with_next-intl.md +3 -3
- package/docs/ar/intlayer_with_react_router_v7.md +72 -16
- package/docs/ar/intlayer_with_react_router_v7_fs_routes.md +2 -0
- package/docs/de/intlayer_with_next-i18next.md +3 -3
- package/docs/de/intlayer_with_next-intl.md +3 -3
- package/docs/de/intlayer_with_react_router_v7.md +72 -15
- package/docs/de/intlayer_with_react_router_v7_fs_routes.md +95 -19
- package/docs/en/configuration.md +1 -0
- package/docs/en/intlayer_with_next-i18next.md +3 -3
- package/docs/en/intlayer_with_next-intl.md +3 -3
- package/docs/en/intlayer_with_react_router_v7.md +74 -15
- package/docs/en/intlayer_with_react_router_v7_fs_routes.md +98 -19
- package/docs/en-GB/configuration.md +1 -0
- package/docs/en-GB/intlayer_with_next-i18next.md +3 -3
- package/docs/en-GB/intlayer_with_next-intl.md +3 -3
- package/docs/en-GB/intlayer_with_react_router_v7.md +73 -16
- package/docs/en-GB/intlayer_with_react_router_v7_fs_routes.md +2 -0
- package/docs/es/intlayer_with_next-i18next.md +3 -3
- package/docs/es/intlayer_with_next-intl.md +3 -3
- package/docs/es/intlayer_with_react_router_v7.md +72 -15
- package/docs/es/intlayer_with_react_router_v7_fs_routes.md +95 -19
- package/docs/fr/intlayer_with_next-i18next.md +3 -3
- package/docs/fr/intlayer_with_next-intl.md +3 -3
- package/docs/fr/intlayer_with_react_router_v7.md +72 -15
- package/docs/fr/intlayer_with_react_router_v7_fs_routes.md +95 -19
- package/docs/hi/intlayer_with_next-i18next.md +3 -3
- package/docs/hi/intlayer_with_next-intl.md +3 -3
- package/docs/hi/intlayer_with_react_router_v7.md +72 -16
- package/docs/hi/intlayer_with_react_router_v7_fs_routes.md +2 -0
- package/docs/id/intlayer_with_next-i18next.md +3 -3
- package/docs/id/intlayer_with_next-intl.md +3 -3
- package/docs/id/intlayer_with_react_router_v7.md +72 -15
- package/docs/id/intlayer_with_react_router_v7_fs_routes.md +2 -0
- package/docs/it/intlayer_with_next-i18next.md +3 -3
- package/docs/it/intlayer_with_next-intl.md +3 -3
- package/docs/it/intlayer_with_react_router_v7.md +72 -15
- package/docs/it/intlayer_with_react_router_v7_fs_routes.md +95 -19
- package/docs/ja/intlayer_with_next-i18next.md +3 -3
- package/docs/ja/intlayer_with_next-intl.md +3 -3
- package/docs/ja/intlayer_with_react_router_v7.md +72 -15
- package/docs/ja/intlayer_with_react_router_v7_fs_routes.md +95 -19
- package/docs/ko/intlayer_with_next-i18next.md +3 -3
- package/docs/ko/intlayer_with_next-intl.md +3 -3
- package/docs/ko/intlayer_with_react_router_v7.md +72 -15
- package/docs/ko/intlayer_with_react_router_v7_fs_routes.md +2 -0
- package/docs/pl/intlayer_with_next-i18next.md +3 -3
- package/docs/pl/intlayer_with_next-intl.md +3 -3
- package/docs/pl/intlayer_with_react_router_v7.md +45 -13
- package/docs/pl/intlayer_with_react_router_v7_fs_routes.md +94 -18
- package/docs/pt/intlayer_with_next-i18next.md +3 -3
- package/docs/pt/intlayer_with_next-intl.md +3 -3
- package/docs/pt/intlayer_with_react_router_v7.md +79 -46
- package/docs/pt/intlayer_with_react_router_v7_fs_routes.md +95 -19
- package/docs/ru/intlayer_with_next-i18next.md +3 -3
- package/docs/ru/intlayer_with_next-intl.md +3 -3
- package/docs/ru/intlayer_with_react_router_v7.md +72 -15
- package/docs/ru/intlayer_with_react_router_v7_fs_routes.md +95 -19
- package/docs/tr/intlayer_with_next-i18next.md +3 -3
- package/docs/tr/intlayer_with_next-intl.md +3 -3
- package/docs/tr/intlayer_with_react_router_v7.md +72 -15
- package/docs/tr/intlayer_with_react_router_v7_fs_routes.md +95 -19
- package/docs/vi/intlayer_with_next-i18next.md +3 -3
- package/docs/vi/intlayer_with_next-intl.md +3 -3
- package/docs/vi/intlayer_with_react_router_v7.md +72 -15
- package/docs/vi/intlayer_with_react_router_v7_fs_routes.md +2 -0
- package/docs/zh/intlayer_with_next-i18next.md +3 -3
- package/docs/zh/intlayer_with_next-intl.md +3 -3
- package/docs/zh/intlayer_with_react_router_v7.md +72 -15
- package/docs/zh/intlayer_with_react_router_v7_fs_routes.md +2 -0
- package/package.json +6 -6
|
@@ -32,6 +32,8 @@ history:
|
|
|
32
32
|
|
|
33
33
|
यह गाइड दिखाता है कि कैसे **Intlayer** को React Router v7 प्रोजेक्ट्स में seamless अंतरराष्ट्रीयकरण के लिए एकीकृत किया जाए, जिसमें locale-aware रूटिंग, TypeScript समर्थन, और आधुनिक विकास प्रथाएँ शामिल हैं।
|
|
34
34
|
|
|
35
|
+
क्लाइंट-साइड रूटिंग के लिए, [Intlayer के साथ React Router v7](https://github.com/aymericzip/intlayer/blob/main/docs/docs/hi/intlayer_with_react_router_v7.md) गाइड देखें।
|
|
36
|
+
|
|
35
37
|
## Table of Contents
|
|
36
38
|
|
|
37
39
|
<TOC/>
|
|
@@ -553,15 +553,15 @@ Intlayer membantu Anda menjaga sinkronisasi terjemahan JSON, menguji kunci yang
|
|
|
553
553
|
Pasang dependensi intlayer:
|
|
554
554
|
|
|
555
555
|
```bash packageManager="npm"
|
|
556
|
-
npm install intlayer @intlayer/sync-json-plugin
|
|
556
|
+
npm install intlayer @intlayer/sync-json-plugin --save-dev
|
|
557
557
|
```
|
|
558
558
|
|
|
559
559
|
```bash packageManager="pnpm"
|
|
560
|
-
pnpm add intlayer @intlayer/sync-json-plugin
|
|
560
|
+
pnpm add intlayer @intlayer/sync-json-plugin --save-dev
|
|
561
561
|
```
|
|
562
562
|
|
|
563
563
|
```bash packageManager="yarn"
|
|
564
|
-
yarn add intlayer @intlayer/sync-json-plugin
|
|
564
|
+
yarn add intlayer @intlayer/sync-json-plugin --dev
|
|
565
565
|
```
|
|
566
566
|
|
|
567
567
|
```ts fileName="intlayer.config.ts"
|
|
@@ -391,15 +391,15 @@ export const config = {
|
|
|
391
391
|
Pasang dependensi intlayer:
|
|
392
392
|
|
|
393
393
|
```bash packageManager="npm"
|
|
394
|
-
npm install intlayer @intlayer/sync-json-plugin
|
|
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
|
|
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
|
|
402
|
+
pnpm add intlayer @intlayer/sync-json-plugin --save-dev
|
|
403
403
|
```
|
|
404
404
|
|
|
405
405
|
Buat file konfigurasi intlayer:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-04
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-27
|
|
4
4
|
title: Cara menerjemahkan aplikasi React Router v7 Anda – panduan i18n 2025
|
|
5
5
|
description: Pelajari cara menambahkan internasionalisasi (i18n) ke aplikasi React Router v7 Anda menggunakan Intlayer. Ikuti panduan komprehensif ini untuk membuat aplikasi Anda multibahasa dengan routing yang mendukung locale.
|
|
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: Perbarui Layout dan tangani 404
|
|
23
26
|
- version: 6.1.5
|
|
24
27
|
date: 2025-10-03
|
|
25
28
|
changes: Memperbarui dokumen
|
|
@@ -179,10 +182,8 @@ Atur konfigurasi routing Anda dengan rute yang mendukung lokal:
|
|
|
179
182
|
import { layout, route, type RouteConfig } from "@react-router/dev/routes";
|
|
180
183
|
|
|
181
184
|
export default [
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
route("/:lang?/about", "routes/about/page.tsx"), // Halaman about yang dilokalkan
|
|
185
|
-
]),
|
|
185
|
+
route("/:lang?", "routes/page.tsx"), // Halaman beranda yang dilokalkan
|
|
186
|
+
route("/:lang?/about", "routes/about/page.tsx"), // Halaman about yang dilokalkan
|
|
186
187
|
] satisfies RouteConfig;
|
|
187
188
|
```
|
|
188
189
|
|
|
@@ -192,19 +193,50 @@ Atur layout root Anda dan layout spesifik lokal:
|
|
|
192
193
|
|
|
193
194
|
#### Layout Root
|
|
194
195
|
|
|
195
|
-
```tsx fileName="app/
|
|
196
|
+
```tsx fileName="app/root.tsx"
|
|
197
|
+
import { getLocaleFromPath } from "intlayer";
|
|
196
198
|
import { IntlayerProvider } from "react-intlayer";
|
|
197
|
-
import {
|
|
199
|
+
import {
|
|
200
|
+
data,
|
|
201
|
+
Meta,
|
|
202
|
+
Scripts,
|
|
203
|
+
ScrollRestoration,
|
|
204
|
+
useLoaderData,
|
|
205
|
+
} from "react-router";
|
|
206
|
+
import type { Route } from "./+types/root";
|
|
198
207
|
|
|
199
|
-
|
|
208
|
+
// ... Unchanged App, links and ErrorBoundary code
|
|
200
209
|
|
|
201
|
-
export
|
|
202
|
-
const
|
|
210
|
+
export async function loader({ request }: Route.LoaderArgs) {
|
|
211
|
+
const locale = getLocaleFromPath(request.url);
|
|
212
|
+
|
|
213
|
+
if (!locale) {
|
|
214
|
+
throw data("Language not supported", { status: 404 });
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return { locale };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function Layout({
|
|
221
|
+
children,
|
|
222
|
+
}: { children: React.ReactNode } & Route.ComponentProps) {
|
|
223
|
+
const data = useLoaderData<typeof loader>();
|
|
224
|
+
const { locale } = data ?? {};
|
|
203
225
|
|
|
204
226
|
return (
|
|
205
|
-
<
|
|
206
|
-
<
|
|
207
|
-
|
|
227
|
+
<html lang={locale}>
|
|
228
|
+
<head>
|
|
229
|
+
<meta charSet="utf-8" />
|
|
230
|
+
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
|
231
|
+
<Meta />
|
|
232
|
+
<Links />
|
|
233
|
+
</head>
|
|
234
|
+
<body>
|
|
235
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
236
|
+
<ScrollRestoration />
|
|
237
|
+
<Scripts />
|
|
238
|
+
</body>
|
|
239
|
+
</html>
|
|
208
240
|
);
|
|
209
241
|
}
|
|
210
242
|
```
|
|
@@ -316,9 +348,34 @@ Akses kamus konten Anda di seluruh aplikasi:
|
|
|
316
348
|
|
|
317
349
|
#### Halaman Beranda yang Dilokalkan
|
|
318
350
|
|
|
319
|
-
```tsx fileName="app/routes/
|
|
351
|
+
```tsx fileName="app/routes/page.tsx"
|
|
352
|
+
import { getIntlayer, validatePrefix } from "intlayer";
|
|
320
353
|
import { useIntlayer } from "react-intlayer";
|
|
321
|
-
import {
|
|
354
|
+
import { data } from "react-router";
|
|
355
|
+
|
|
356
|
+
import { LocaleSwitcher } from "~/components/locale-switcher";
|
|
357
|
+
|
|
358
|
+
import { Navbar } from "~/components/navbar";
|
|
359
|
+
import type { Route } from "./+types/page";
|
|
360
|
+
|
|
361
|
+
export const loader = ({ params }: Route.LoaderArgs) => {
|
|
362
|
+
const { locale } = params;
|
|
363
|
+
|
|
364
|
+
const { isValid } = validatePrefix(locale);
|
|
365
|
+
|
|
366
|
+
if (!isValid) {
|
|
367
|
+
throw data("Locale not supported", { status: 404 });
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
export const meta: Route.MetaFunction = ({ params }) => {
|
|
372
|
+
const content = getIntlayer("page", params.locale);
|
|
373
|
+
|
|
374
|
+
return [
|
|
375
|
+
{ title: content.title },
|
|
376
|
+
{ content: content.description, name: "description" },
|
|
377
|
+
];
|
|
378
|
+
};
|
|
322
379
|
|
|
323
380
|
export default function Page() {
|
|
324
381
|
const { title, description, aboutLink } = useIntlayer("page");
|
|
@@ -32,6 +32,8 @@ history:
|
|
|
32
32
|
|
|
33
33
|
Panduan ini menunjukkan cara mengintegrasikan **Intlayer** untuk internasionalisasi yang mulus dalam proyek React Router v7 dengan routing yang mendukung locale, dukungan TypeScript, dan praktik pengembangan modern.
|
|
34
34
|
|
|
35
|
+
Untuk routing sisi klien, lihat panduan [Intlayer dengan React Router v7](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/intlayer_with_react_router_v7.md).
|
|
36
|
+
|
|
35
37
|
## Table of Contents
|
|
36
38
|
|
|
37
39
|
<TOC/>
|
|
@@ -553,15 +553,15 @@ Intlayer ti aiuta a mantenere sincronizzate le traduzioni JSON, testare le chiav
|
|
|
553
553
|
Installa le dipendenze di intlayer:
|
|
554
554
|
|
|
555
555
|
```bash packageManager="npm"
|
|
556
|
-
npm install intlayer @intlayer/sync-json-plugin
|
|
556
|
+
npm install intlayer @intlayer/sync-json-plugin --save-dev
|
|
557
557
|
```
|
|
558
558
|
|
|
559
559
|
```bash packageManager="pnpm"
|
|
560
|
-
pnpm add intlayer @intlayer/sync-json-plugin
|
|
560
|
+
pnpm add intlayer @intlayer/sync-json-plugin --save-dev
|
|
561
561
|
```
|
|
562
562
|
|
|
563
563
|
```bash packageManager="yarn"
|
|
564
|
-
yarn add intlayer @intlayer/sync-json-plugin
|
|
564
|
+
yarn add intlayer @intlayer/sync-json-plugin --dev
|
|
565
565
|
```
|
|
566
566
|
|
|
567
567
|
```ts fileName="intlayer.config.ts"
|
|
@@ -391,15 +391,15 @@ export const config = {
|
|
|
391
391
|
Installa le dipendenze di intlayer:
|
|
392
392
|
|
|
393
393
|
```bash packageManager="npm"
|
|
394
|
-
npm install intlayer @intlayer/sync-json-plugin
|
|
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
|
|
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
|
|
402
|
+
pnpm add intlayer @intlayer/sync-json-plugin --save-dev
|
|
403
403
|
```
|
|
404
404
|
|
|
405
405
|
Crea il file di configurazione di intlayer:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-04
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-27
|
|
4
4
|
title: Come tradurre la tua React Router v7 – guida i18n 2025
|
|
5
5
|
description: Scopri come aggiungere l'internazionalizzazione (i18n) alla tua applicazione React Router v7 utilizzando Intlayer. Segui questa guida completa per rendere la tua app multilingue con il routing consapevole della localizzazione.
|
|
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: Aggiorna Layout e gestisci 404
|
|
23
26
|
- version: 6.1.5
|
|
24
27
|
date: 2025-10-03
|
|
25
28
|
changes: Documentazione aggiornata
|
|
@@ -173,10 +176,8 @@ Configura la tua configurazione di routing con rotte consapevoli della localizza
|
|
|
173
176
|
import { layout, route, type RouteConfig } from "@react-router/dev/routes";
|
|
174
177
|
|
|
175
178
|
export default [
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
route("/:lang?/about", "routes/about/page.tsx"), // Pagina "about" localizzata
|
|
179
|
-
]),
|
|
179
|
+
route("/:lang?", "routes/page.tsx"), // Pagina iniziale localizzata
|
|
180
|
+
route("/:lang?/about", "routes/about/page.tsx"), // Pagina "about" localizzata
|
|
180
181
|
] satisfies RouteConfig;
|
|
181
182
|
```
|
|
182
183
|
|
|
@@ -186,19 +187,50 @@ Configura il layout principale e i layout specifici per la localizzazione:
|
|
|
186
187
|
|
|
187
188
|
#### Layout Principale
|
|
188
189
|
|
|
189
|
-
```tsx fileName="app/
|
|
190
|
+
```tsx fileName="app/root.tsx"
|
|
191
|
+
import { getLocaleFromPath } from "intlayer";
|
|
190
192
|
import { IntlayerProvider } from "react-intlayer";
|
|
191
|
-
import {
|
|
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
|
-
|
|
202
|
+
// ... Unchanged App, links and ErrorBoundary code
|
|
194
203
|
|
|
195
|
-
export
|
|
196
|
-
const
|
|
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
|
-
<
|
|
200
|
-
<
|
|
201
|
-
|
|
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 @@ Accedi ai tuoi dizionari di contenuti in tutta l'applicazione:
|
|
|
312
344
|
|
|
313
345
|
#### Pagina Home Localizzata
|
|
314
346
|
|
|
315
|
-
```tsx fileName="app/routes/
|
|
347
|
+
```tsx fileName="app/routes/page.tsx"
|
|
348
|
+
import { getIntlayer, validatePrefix } from "intlayer";
|
|
316
349
|
import { useIntlayer } from "react-intlayer";
|
|
317
|
-
import {
|
|
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
|
Questa guida dimostra come integrare **Intlayer** per un'internazionalizzazione senza soluzione di continuità nei progetti React Router v7 usando **routing basato sul file system** (`@react-router/fs-routes`) con routing consapevole della localizzazione, supporto TypeScript e pratiche di sviluppo moderne.
|
|
33
33
|
|
|
34
|
+
Per il routing lato client, fare riferimento alla guida [Intlayer con React Router v7](https://github.com/aymericzip/intlayer/blob/main/docs/docs/it/intlayer_with_react_router_v7.md).
|
|
35
|
+
|
|
34
36
|
## Table of Contents
|
|
35
37
|
|
|
36
38
|
<TOC/>
|
|
@@ -197,12 +199,13 @@ Crea i seguenti file nella directory `app/routes/`:
|
|
|
197
199
|
#### Struttura dei file
|
|
198
200
|
|
|
199
201
|
```bash
|
|
200
|
-
app/
|
|
201
|
-
├──
|
|
202
|
-
|
|
203
|
-
├── ($locale)._index.
|
|
204
|
-
├── ($locale).
|
|
205
|
-
|
|
202
|
+
app/
|
|
203
|
+
├── root.tsx # Wrapper di layout per le rotte di locale
|
|
204
|
+
└──routes/
|
|
205
|
+
├── ($locale)._index.tsx # Pagina iniziale (/, /es, ecc.)
|
|
206
|
+
├── ($locale)._index.content.ts # Contenuto della pagina iniziale
|
|
207
|
+
├── ($locale).about.tsx # Pagina About (/about, /es/about, ecc.)
|
|
208
|
+
└── ($locale).about.content.ts # Contenuto della pagina About
|
|
206
209
|
```
|
|
207
210
|
|
|
208
211
|
Le convenzioni di denominazione:
|
|
@@ -214,23 +217,50 @@ Le convenzioni di denominazione:
|
|
|
214
217
|
|
|
215
218
|
#### Componente Layout
|
|
216
219
|
|
|
217
|
-
```tsx fileName="app/
|
|
220
|
+
```tsx fileName="app/root.tsx"
|
|
221
|
+
import { getLocaleFromPath } from "intlayer";
|
|
218
222
|
import { IntlayerProvider } from "react-intlayer";
|
|
219
|
-
import {
|
|
223
|
+
import {
|
|
224
|
+
isRouteErrorResponse,
|
|
225
|
+
Meta,
|
|
226
|
+
Outlet,
|
|
227
|
+
Scripts,
|
|
228
|
+
ScrollRestoration,
|
|
229
|
+
useLoaderData,
|
|
230
|
+
} from "react-router";
|
|
220
231
|
|
|
221
|
-
import {
|
|
232
|
+
import type { Route } from "./+types/root";
|
|
222
233
|
|
|
223
|
-
import
|
|
234
|
+
import "./app.css";
|
|
224
235
|
|
|
225
|
-
|
|
226
|
-
useI18nHTMLAttributes();
|
|
236
|
+
// links and ErrorBoundary code
|
|
227
237
|
|
|
228
|
-
|
|
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
|
-
<
|
|
232
|
-
<
|
|
233
|
-
|
|
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
|
#### Pagina Indice
|
|
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 {
|
|
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
|
#### Pagina About
|
|
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 {
|
|
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
|
-
Questo hook è già utilizzato nel componente di layout (`
|
|
565
|
+
Questo hook è già utilizzato nel componente di layout (`root.tsx`) mostrato nel Passo 5.
|
|
490
566
|
|
|
491
567
|
### Passo 10: Aggiungere il middleware (Opzionale)
|
|
492
568
|
|
|
@@ -552,15 +552,15 @@ IntlayerはJSON翻訳の同期を保ち、不足しているキーのテスト
|
|
|
552
552
|
intlayerの依存関係をインストールします:
|
|
553
553
|
|
|
554
554
|
```bash packageManager="npm"
|
|
555
|
-
npm install intlayer @intlayer/sync-json-plugin
|
|
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
|
|
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
|
|
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
|
intlayer の依存関係をインストールします:
|
|
392
392
|
|
|
393
393
|
```bash packageManager="npm"
|
|
394
|
-
npm install intlayer @intlayer/sync-json-plugin
|
|
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
|
|
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
|
|
402
|
+
pnpm add intlayer @intlayer/sync-json-plugin --save-dev
|
|
403
403
|
```
|
|
404
404
|
|
|
405
405
|
intlayer の設定ファイルを作成します:
|