@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-04
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-27
|
|
4
4
|
title: Cách dịch ứng dụng React Router v7 của bạn – hướng dẫn i18n 2025
|
|
5
5
|
description: Tìm hiểu cách thêm quốc tế hóa (i18n) vào ứng dụng React Router v7 của bạn bằng Intlayer. Theo dõi hướng dẫn toàn diện này để làm cho ứng dụng của bạn đa ngôn ngữ với định tuyến nhận biết 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: Cập nhật Layout và xử lý 404
|
|
23
26
|
- version: 6.1.5
|
|
24
27
|
date: 2025-10-03
|
|
25
28
|
changes: Cập nhật tài liệu
|
|
@@ -181,10 +184,8 @@ Thiết lập cấu hình routing với các route nhận biết ngôn ngữ:
|
|
|
181
184
|
import { layout, route, type RouteConfig } from "@react-router/dev/routes";
|
|
182
185
|
|
|
183
186
|
export default [
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
route("/:lang?/about", "routes/about/page.tsx"), // Trang about có hỗ trợ đa ngôn ngữ
|
|
187
|
-
]),
|
|
187
|
+
route("/:lang?", "routes/page.tsx"), // Trang chủ có hỗ trợ đa ngôn ngữ
|
|
188
|
+
route("/:lang?/about", "routes/about/page.tsx"), // Trang about có hỗ trợ đa ngôn ngữ
|
|
188
189
|
] satisfies RouteConfig;
|
|
189
190
|
```
|
|
190
191
|
|
|
@@ -194,19 +195,50 @@ Thiết lập root layout và các layout theo ngôn ngữ cụ thể:
|
|
|
194
195
|
|
|
195
196
|
#### Root Layout
|
|
196
197
|
|
|
197
|
-
```tsx fileName="app/
|
|
198
|
+
```tsx fileName="app/root.tsx"
|
|
199
|
+
import { getLocaleFromPath } from "intlayer";
|
|
198
200
|
import { IntlayerProvider } from "react-intlayer";
|
|
199
|
-
import {
|
|
201
|
+
import {
|
|
202
|
+
data,
|
|
203
|
+
Meta,
|
|
204
|
+
Scripts,
|
|
205
|
+
ScrollRestoration,
|
|
206
|
+
useLoaderData,
|
|
207
|
+
} from "react-router";
|
|
208
|
+
import type { Route } from "./+types/root";
|
|
200
209
|
|
|
201
|
-
|
|
210
|
+
// ... Unchanged App, links and ErrorBoundary code
|
|
202
211
|
|
|
203
|
-
export
|
|
204
|
-
const
|
|
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 ?? {};
|
|
205
227
|
|
|
206
228
|
return (
|
|
207
|
-
<
|
|
208
|
-
<
|
|
209
|
-
|
|
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>
|
|
210
242
|
);
|
|
211
243
|
}
|
|
212
244
|
```
|
|
@@ -318,9 +350,34 @@ Truy cập các từ điển nội dung của bạn trong toàn bộ ứng dụn
|
|
|
318
350
|
|
|
319
351
|
#### Trang Chủ Đã Được Địa Phương Hóa
|
|
320
352
|
|
|
321
|
-
```tsx fileName="app/routes/
|
|
353
|
+
```tsx fileName="app/routes/page.tsx"
|
|
354
|
+
import { getIntlayer, validatePrefix } from "intlayer";
|
|
322
355
|
import { useIntlayer } from "react-intlayer";
|
|
323
|
-
import {
|
|
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
|
+
};
|
|
324
381
|
|
|
325
382
|
export default function Page() {
|
|
326
383
|
const { title, description, aboutLink } = useIntlayer("page");
|
|
@@ -32,6 +32,8 @@ history:
|
|
|
32
32
|
|
|
33
33
|
Hướng dẫn này trình bày cách tích hợp **Intlayer** để thực hiện quốc tế hóa liền mạch trong các dự án React Router v7 với định tuyến nhận biết locale, hỗ trợ TypeScript và các thực hành phát triển hiện đại.
|
|
34
34
|
|
|
35
|
+
Đối với định tuyến phía máy khách, hãy tham khảo hướng dẫn [Intlayer với React Router v7](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/intlayer_with_react_router_v7.md).
|
|
36
|
+
|
|
35
37
|
## Table of Contents
|
|
36
38
|
|
|
37
39
|
<TOC/>
|
|
@@ -553,15 +553,15 @@ Intlayer 帮助你保持 JSON 翻译同步,测试缺失的键,并在需要
|
|
|
553
553
|
安装 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"
|
|
@@ -393,15 +393,15 @@ export const config = {
|
|
|
393
393
|
安装 intlayer 依赖:
|
|
394
394
|
|
|
395
395
|
```bash packageManager="npm"
|
|
396
|
-
npm install intlayer @intlayer/sync-json-plugin
|
|
396
|
+
npm install intlayer @intlayer/sync-json-plugin --save-dev
|
|
397
397
|
```
|
|
398
398
|
|
|
399
399
|
```bash packageManager="yarn"
|
|
400
|
-
yarn add intlayer @intlayer/sync-json-plugin
|
|
400
|
+
yarn add intlayer @intlayer/sync-json-plugin --dev
|
|
401
401
|
```
|
|
402
402
|
|
|
403
403
|
```bash packageManager="pnpm"
|
|
404
|
-
pnpm add intlayer @intlayer/sync-json-plugin
|
|
404
|
+
pnpm add intlayer @intlayer/sync-json-plugin --save-dev
|
|
405
405
|
```
|
|
406
406
|
|
|
407
407
|
创建 intlayer 配置文件:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-04
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-27
|
|
4
4
|
title: 如何翻译您的React Router v7应用 – i18n指南 2025
|
|
5
5
|
description: 学习如何使用 Intlayer 为您的 React Router v7 应用添加国际化(i18n)。按照本综合指南,使您的应用支持多语言和基于区域的路由。
|
|
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: 更新文档
|
|
@@ -174,10 +177,8 @@ export default defineConfig({
|
|
|
174
177
|
import { layout, route, type RouteConfig } from "@react-router/dev/routes";
|
|
175
178
|
|
|
176
179
|
export default [
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
route("/:lang?/about", "routes/about/page.tsx"), // 本地化关于页面
|
|
180
|
-
]),
|
|
180
|
+
route("/:lang?", "routes/page.tsx"), // 本地化主页
|
|
181
|
+
route("/:lang?/about", "routes/about/page.tsx"), // 本地化关于页面
|
|
181
182
|
] satisfies RouteConfig;
|
|
182
183
|
```
|
|
183
184
|
|
|
@@ -187,19 +188,50 @@ export default [
|
|
|
187
188
|
|
|
188
189
|
#### 根布局
|
|
189
190
|
|
|
190
|
-
```tsx fileName="app/
|
|
191
|
+
```tsx fileName="app/root.tsx"
|
|
192
|
+
import { getLocaleFromPath } from "intlayer";
|
|
191
193
|
import { IntlayerProvider } from "react-intlayer";
|
|
192
|
-
import {
|
|
194
|
+
import {
|
|
195
|
+
data,
|
|
196
|
+
Meta,
|
|
197
|
+
Scripts,
|
|
198
|
+
ScrollRestoration,
|
|
199
|
+
useLoaderData,
|
|
200
|
+
} from "react-router";
|
|
201
|
+
import type { Route } from "./+types/root";
|
|
193
202
|
|
|
194
|
-
|
|
203
|
+
// ... Unchanged App, links and ErrorBoundary code
|
|
195
204
|
|
|
196
|
-
export
|
|
197
|
-
const
|
|
205
|
+
export async function loader({ request }: Route.LoaderArgs) {
|
|
206
|
+
const locale = getLocaleFromPath(request.url);
|
|
207
|
+
|
|
208
|
+
if (!locale) {
|
|
209
|
+
throw data("Language not supported", { status: 404 });
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return { locale };
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export function Layout({
|
|
216
|
+
children,
|
|
217
|
+
}: { children: React.ReactNode } & Route.ComponentProps) {
|
|
218
|
+
const data = useLoaderData<typeof loader>();
|
|
219
|
+
const { locale } = data ?? {};
|
|
198
220
|
|
|
199
221
|
return (
|
|
200
|
-
<
|
|
201
|
-
<
|
|
202
|
-
|
|
222
|
+
<html lang={locale}>
|
|
223
|
+
<head>
|
|
224
|
+
<meta charSet="utf-8" />
|
|
225
|
+
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
|
226
|
+
<Meta />
|
|
227
|
+
<Links />
|
|
228
|
+
</head>
|
|
229
|
+
<body>
|
|
230
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
231
|
+
<ScrollRestoration />
|
|
232
|
+
<Scripts />
|
|
233
|
+
</body>
|
|
234
|
+
</html>
|
|
203
235
|
);
|
|
204
236
|
}
|
|
205
237
|
```
|
|
@@ -311,9 +343,34 @@ export const useLocalizedNavigate = () => {
|
|
|
311
343
|
|
|
312
344
|
#### 本地化主页
|
|
313
345
|
|
|
314
|
-
```tsx fileName="app/routes/
|
|
346
|
+
```tsx fileName="app/routes/page.tsx"
|
|
347
|
+
import { getIntlayer, validatePrefix } from "intlayer";
|
|
315
348
|
import { useIntlayer } from "react-intlayer";
|
|
316
|
-
import {
|
|
349
|
+
import { data } from "react-router";
|
|
350
|
+
|
|
351
|
+
import { LocaleSwitcher } from "~/components/locale-switcher";
|
|
352
|
+
|
|
353
|
+
import { Navbar } from "~/components/navbar";
|
|
354
|
+
import type { Route } from "./+types/page";
|
|
355
|
+
|
|
356
|
+
export const loader = ({ params }: Route.LoaderArgs) => {
|
|
357
|
+
const { locale } = params;
|
|
358
|
+
|
|
359
|
+
const { isValid } = validatePrefix(locale);
|
|
360
|
+
|
|
361
|
+
if (!isValid) {
|
|
362
|
+
throw data("Locale not supported", { status: 404 });
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
export const meta: Route.MetaFunction = ({ params }) => {
|
|
367
|
+
const content = getIntlayer("page", params.locale);
|
|
368
|
+
|
|
369
|
+
return [
|
|
370
|
+
{ title: content.title },
|
|
371
|
+
{ content: content.description, name: "description" },
|
|
372
|
+
];
|
|
373
|
+
};
|
|
317
374
|
|
|
318
375
|
export default function Page() {
|
|
319
376
|
const { title, description, aboutLink } = useIntlayer("page");
|
|
@@ -32,6 +32,8 @@ history:
|
|
|
32
32
|
|
|
33
33
|
本指南演示了如何在 React Router v7 项目中集成 **Intlayer**,实现无缝国际化,支持基于区域的路由、TypeScript 支持以及现代开发实践。
|
|
34
34
|
|
|
35
|
+
对于客户端路由,请参阅 [Intlayer 与 React Router v7](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_with_react_router_v7.md) 指南。
|
|
36
|
+
|
|
35
37
|
## Table of Contents
|
|
36
38
|
|
|
37
39
|
<TOC/>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/docs",
|
|
3
|
-
"version": "7.5.
|
|
3
|
+
"version": "7.5.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Intlayer documentation",
|
|
6
6
|
"keywords": [
|
|
@@ -73,13 +73,13 @@
|
|
|
73
73
|
"watch": "webpack --config ./webpack.config.ts --watch"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@intlayer/config": "7.5.
|
|
77
|
-
"@intlayer/core": "7.5.
|
|
78
|
-
"@intlayer/types": "7.5.
|
|
76
|
+
"@intlayer/config": "7.5.7",
|
|
77
|
+
"@intlayer/core": "7.5.7",
|
|
78
|
+
"@intlayer/types": "7.5.7"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@intlayer/api": "7.5.
|
|
82
|
-
"@intlayer/cli": "7.5.
|
|
81
|
+
"@intlayer/api": "7.5.7",
|
|
82
|
+
"@intlayer/cli": "7.5.7",
|
|
83
83
|
"@types/node": "25.0.3",
|
|
84
84
|
"@utils/ts-config": "1.0.4",
|
|
85
85
|
"@utils/ts-config-types": "1.0.4",
|