@intlayer/docs 7.1.0 → 7.1.1-canary.0
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/internationalization_and_SEO.md +0 -4
- package/blog/ar/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/de/internationalization_and_SEO.md +0 -2
- package/blog/en/internationalization_and_SEO.md +0 -2
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/en-GB/internationalization_and_SEO.md +0 -2
- package/blog/es/internationalization_and_SEO.md +0 -4
- package/blog/fr/internationalization_and_SEO.md +0 -2
- package/blog/hi/internationalization_and_SEO.md +0 -2
- package/blog/id/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/it/internationalization_and_SEO.md +0 -2
- package/blog/ja/internationalization_and_SEO.md +0 -2
- package/blog/ko/internationalization_and_SEO.md +0 -2
- package/blog/pl/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/pt/internationalization_and_SEO.md +0 -4
- package/blog/ru/internationalization_and_SEO.md +0 -4
- package/blog/vi/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/zh/internationalization_and_SEO.md +0 -4
- package/docs/ar/intlayer_with_nextjs_14.md +9 -9
- package/docs/ar/intlayer_with_nextjs_15.md +9 -8
- package/docs/ar/intlayer_with_nextjs_16.md +2 -56
- package/docs/ar/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/ar/intlayer_with_react_router_v7.md +6 -6
- package/docs/ar/intlayer_with_tanstack.md +46 -31
- package/docs/ar/intlayer_with_vite+preact.md +7 -7
- package/docs/ar/intlayer_with_vite+react.md +7 -7
- package/docs/ar/intlayer_with_vite+vue.md +9 -9
- package/docs/de/intlayer_with_nextjs_14.md +9 -9
- package/docs/de/intlayer_with_nextjs_15.md +9 -8
- package/docs/de/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/de/intlayer_with_react_router_v7.md +6 -6
- package/docs/de/intlayer_with_tanstack.md +46 -31
- package/docs/de/intlayer_with_vite+preact.md +7 -7
- package/docs/de/intlayer_with_vite+react.md +7 -7
- package/docs/de/intlayer_with_vite+vue.md +9 -9
- package/docs/en/interest_of_intlayer.md +1 -1
- package/docs/en/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/en/intlayer_with_react_router_v7.md +6 -6
- package/docs/en/intlayer_with_tanstack.md +57 -33
- package/docs/en/intlayer_with_vite+preact.md +8 -8
- package/docs/en/intlayer_with_vite+react.md +8 -8
- package/docs/en/intlayer_with_vite+vue.md +8 -8
- package/docs/en/releases/v6.md +1 -1
- package/docs/en-GB/intlayer_with_nextjs_14.md +9 -9
- package/docs/en-GB/intlayer_with_nextjs_15.md +9 -8
- package/docs/en-GB/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/en-GB/intlayer_with_react_router_v7.md +6 -6
- package/docs/en-GB/intlayer_with_tanstack.md +46 -31
- package/docs/en-GB/intlayer_with_vite+preact.md +7 -7
- package/docs/en-GB/intlayer_with_vite+react.md +7 -7
- package/docs/en-GB/intlayer_with_vite+vue.md +9 -9
- package/docs/es/intlayer_with_nextjs_14.md +9 -9
- package/docs/es/intlayer_with_nextjs_15.md +9 -8
- package/docs/es/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/es/intlayer_with_react_router_v7.md +6 -6
- package/docs/es/intlayer_with_tanstack.md +15 -10
- package/docs/es/intlayer_with_vite+preact.md +7 -7
- package/docs/es/intlayer_with_vite+react.md +7 -7
- package/docs/es/intlayer_with_vite+vue.md +9 -9
- package/docs/fr/intlayer_with_nextjs_14.md +9 -9
- package/docs/fr/intlayer_with_nextjs_15.md +9 -8
- package/docs/fr/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/fr/intlayer_with_react_router_v7.md +6 -6
- package/docs/fr/intlayer_with_tanstack.md +46 -31
- package/docs/fr/intlayer_with_vite+preact.md +7 -7
- package/docs/fr/intlayer_with_vite+react.md +7 -7
- package/docs/fr/intlayer_with_vite+vue.md +9 -9
- package/docs/hi/intlayer_with_nextjs_14.md +9 -9
- package/docs/hi/intlayer_with_nextjs_15.md +9 -8
- package/docs/hi/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/hi/intlayer_with_react_router_v7.md +6 -6
- package/docs/hi/intlayer_with_tanstack.md +15 -10
- package/docs/hi/intlayer_with_vite+preact.md +7 -7
- package/docs/hi/intlayer_with_vite+react.md +7 -7
- package/docs/hi/intlayer_with_vite+vue.md +9 -9
- package/docs/id/interest_of_intlayer.md +1 -1
- package/docs/id/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/id/intlayer_with_react_router_v7.md +6 -6
- package/docs/id/intlayer_with_tanstack.md +15 -10
- package/docs/id/intlayer_with_vite+preact.md +9 -9
- package/docs/id/intlayer_with_vite+react.md +8 -8
- package/docs/id/intlayer_with_vite+vue.md +8 -8
- package/docs/id/releases/v6.md +1 -1
- package/docs/it/intlayer_with_nextjs_14.md +9 -9
- package/docs/it/intlayer_with_nextjs_15.md +9 -8
- package/docs/it/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/it/intlayer_with_react_router_v7.md +6 -6
- package/docs/it/intlayer_with_tanstack.md +46 -31
- package/docs/it/intlayer_with_vite+preact.md +7 -7
- package/docs/it/intlayer_with_vite+react.md +7 -7
- package/docs/it/intlayer_with_vite+vue.md +9 -9
- package/docs/ja/intlayer_with_nextjs_14.md +9 -9
- package/docs/ja/intlayer_with_nextjs_15.md +9 -8
- package/docs/ja/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/ja/intlayer_with_react_router_v7.md +6 -6
- package/docs/ja/intlayer_with_tanstack.md +16 -10
- package/docs/ja/intlayer_with_vite+preact.md +7 -7
- package/docs/ja/intlayer_with_vite+react.md +7 -7
- package/docs/ja/intlayer_with_vite+vue.md +9 -9
- package/docs/ko/intlayer_with_nextjs_14.md +9 -9
- package/docs/ko/intlayer_with_nextjs_15.md +9 -8
- package/docs/ko/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/ko/intlayer_with_react_router_v7.md +6 -6
- package/docs/ko/intlayer_with_tanstack.md +46 -31
- package/docs/ko/intlayer_with_vite+preact.md +7 -7
- package/docs/ko/intlayer_with_vite+react.md +7 -7
- package/docs/ko/intlayer_with_vite+vue.md +9 -9
- package/docs/pl/interest_of_intlayer.md +1 -1
- package/docs/pl/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/pl/intlayer_with_react_router_v7.md +6 -6
- package/docs/pl/intlayer_with_tanstack.md +15 -10
- package/docs/pl/intlayer_with_vite+preact.md +10 -10
- package/docs/pl/intlayer_with_vite+react.md +8 -8
- package/docs/pl/intlayer_with_vite+vue.md +8 -8
- package/docs/pl/releases/v6.md +1 -1
- package/docs/pt/intlayer_with_nextjs_14.md +9 -9
- package/docs/pt/intlayer_with_nextjs_15.md +9 -8
- package/docs/pt/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/pt/intlayer_with_react_router_v7.md +2 -2
- package/docs/pt/intlayer_with_tanstack.md +46 -31
- package/docs/pt/intlayer_with_vite+preact.md +7 -7
- package/docs/pt/intlayer_with_vite+react.md +7 -7
- package/docs/pt/intlayer_with_vite+vue.md +9 -9
- package/docs/ru/intlayer_with_nextjs_14.md +9 -9
- package/docs/ru/intlayer_with_nextjs_15.md +9 -8
- package/docs/ru/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/ru/intlayer_with_react_router_v7.md +6 -6
- package/docs/ru/intlayer_with_tanstack.md +15 -10
- package/docs/ru/intlayer_with_vite+preact.md +7 -7
- package/docs/ru/intlayer_with_vite+react.md +7 -7
- package/docs/ru/intlayer_with_vite+vue.md +9 -9
- package/docs/tr/interest_of_intlayer.md +1 -1
- package/docs/tr/intlayer_with_nextjs_15.md +9 -8
- package/docs/tr/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/tr/intlayer_with_react_router_v7.md +6 -6
- package/docs/tr/intlayer_with_tanstack.md +46 -31
- package/docs/tr/intlayer_with_vite+preact.md +8 -8
- package/docs/tr/intlayer_with_vite+react.md +8 -8
- package/docs/tr/intlayer_with_vite+vue.md +8 -8
- package/docs/vi/interest_of_intlayer.md +1 -1
- package/docs/vi/intlayer_with_nextjs_15.md +1 -0
- package/docs/vi/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/vi/intlayer_with_react_router_v7.md +6 -6
- package/docs/vi/intlayer_with_tanstack.md +46 -31
- package/docs/vi/intlayer_with_vite+preact.md +9 -9
- package/docs/vi/intlayer_with_vite+react.md +8 -8
- package/docs/vi/intlayer_with_vite+vue.md +8 -8
- package/docs/vi/releases/v6.md +1 -1
- package/docs/zh/intlayer_with_nextjs_14.md +9 -9
- package/docs/zh/intlayer_with_nextjs_15.md +9 -8
- package/docs/zh/intlayer_with_nextjs_page_router.md +7 -10
- package/docs/zh/intlayer_with_react_router_v7.md +6 -6
- package/docs/zh/intlayer_with_tanstack.md +14 -8
- package/docs/zh/intlayer_with_vite+preact.md +7 -7
- package/docs/zh/intlayer_with_vite+react.md +7 -7
- package/docs/zh/intlayer_with_vite+vue.md +7 -7
- package/frequent_questions/ar/domain_routing.md +1 -1
- package/frequent_questions/de/domain_routing.md +1 -1
- package/frequent_questions/en/domain_routing.md +1 -1
- package/frequent_questions/en/package_version_error.md +29 -1
- package/frequent_questions/en-GB/domain_routing.md +1 -1
- package/frequent_questions/es/domain_routing.md +1 -1
- package/frequent_questions/fr/domain_routing.md +1 -1
- package/frequent_questions/hi/domain_routing.md +1 -1
- package/frequent_questions/id/domain_routing.md +1 -1
- package/frequent_questions/it/domain_routing.md +1 -1
- package/frequent_questions/it/package_version_error.md +4 -4
- package/frequent_questions/ja/domain_routing.md +1 -1
- package/frequent_questions/ko/domain_routing.md +1 -1
- package/frequent_questions/pl/domain_routing.md +1 -1
- package/frequent_questions/pt/domain_routing.md +1 -1
- package/frequent_questions/ru/domain_routing.md +1 -1
- package/frequent_questions/tr/domain_routing.md +1 -1
- package/frequent_questions/vi/domain_routing.md +1 -1
- package/frequent_questions/zh/domain_routing.md +1 -1
- package/package.json +7 -14
|
@@ -317,7 +317,7 @@ import {
|
|
|
317
317
|
getLocalizedUrl,
|
|
318
318
|
getPathWithoutLocale,
|
|
319
319
|
} from "intlayer";
|
|
320
|
-
import {
|
|
320
|
+
import { setLocaleInStorage, useIntlayer, useLocale } from "react-intlayer";
|
|
321
321
|
import { Link, useLocation } from "react-router";
|
|
322
322
|
|
|
323
323
|
export const LocaleSwitcher: FC = () => {
|
|
@@ -335,7 +335,7 @@ export const LocaleSwitcher: FC = () => {
|
|
|
335
335
|
<Link
|
|
336
336
|
aria-current={localeItem === locale ? "page" : undefined}
|
|
337
337
|
aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeItem)}`}
|
|
338
|
-
onClick={() =>
|
|
338
|
+
onClick={() => setLocale(localeItem)}
|
|
339
339
|
to={getLocalizedUrl(pathWithoutLocale, localeItem)}
|
|
340
340
|
>
|
|
341
341
|
<span>
|
|
@@ -404,18 +404,18 @@ export default function RootLayout() {
|
|
|
404
404
|
|
|
405
405
|
### الخطوة 11: إضافة الوسيط (اختياري)
|
|
406
406
|
|
|
407
|
-
يمكنك أيضًا استخدام `
|
|
407
|
+
يمكنك أيضًا استخدام `intlayerProxy` لإضافة التوجيه من جانب الخادم إلى تطبيقك. سيقوم هذا المكون الإضافي بالكشف تلقائيًا عن اللغة الحالية بناءً على عنوان URL وتعيين ملف تعريف الارتباط المناسب للغة. إذا لم يتم تحديد لغة، فسيحدد المكون الإضافي اللغة الأنسب بناءً على تفضيلات لغة متصفح المستخدم. إذا لم يتم الكشف عن أي لغة، فسيتم إعادة التوجيه إلى اللغة الافتراضية.
|
|
408
408
|
|
|
409
|
-
> لاحظ أنه لاستخدام `
|
|
409
|
+
> لاحظ أنه لاستخدام `intlayerProxy` في بيئة الإنتاج، تحتاج إلى نقل حزمة `vite-intlayer` من `devDependencies` إلى `dependencies`.
|
|
410
410
|
|
|
411
411
|
```typescript {3,7} fileName="vite.config.ts"
|
|
412
412
|
import { defineConfig } from "vite";
|
|
413
413
|
import react from "@vitejs/plugin-react-swc";
|
|
414
|
-
import { intlayer,
|
|
414
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
415
415
|
|
|
416
416
|
// https://vitejs.dev/config/
|
|
417
417
|
export default defineConfig({
|
|
418
|
-
plugins: [react(), intlayer(),
|
|
418
|
+
plugins: [react(), intlayer(), intlayerProxy()],
|
|
419
419
|
});
|
|
420
420
|
```
|
|
421
421
|
|
|
@@ -200,6 +200,7 @@ import type { FC } from "react";
|
|
|
200
200
|
|
|
201
201
|
import { Link, type LinkComponentProps } from "@tanstack/react-router";
|
|
202
202
|
import { useLocale } from "react-intlayer";
|
|
203
|
+
import { getPrefix } from "intlayer";
|
|
203
204
|
|
|
204
205
|
export const LOCALE_ROUTE = "{-$locale}" as const;
|
|
205
206
|
|
|
@@ -229,12 +230,13 @@ type RemoveLocaleFromString<S extends string> = CollapseDoubleSlashes<
|
|
|
229
230
|
|
|
230
231
|
export const LocalizedLink: FC<LocalizedLinkProps> = (props) => {
|
|
231
232
|
const { locale } = useLocale();
|
|
233
|
+
const { localePrefix } = getPrefix(locale);
|
|
232
234
|
|
|
233
235
|
return (
|
|
234
236
|
<Link
|
|
235
237
|
{...props}
|
|
236
238
|
params={{
|
|
237
|
-
locale,
|
|
239
|
+
locale: localePrefix,
|
|
238
240
|
...(typeof props?.params === "object" ? props?.params : {}),
|
|
239
241
|
}}
|
|
240
242
|
to={`/${LOCALE_ROUTE}${props.to}` as LinkComponentProps["to"]}
|
|
@@ -251,43 +253,52 @@ export const LocalizedLink: FC<LocalizedLinkProps> = (props) => {
|
|
|
251
253
|
بعد ذلك يمكننا إنشاء هوك `useLocalizedNavigate` للملاحة البرمجية:
|
|
252
254
|
|
|
253
255
|
```tsx fileName="src/hooks/useLocalizedNavigate.tsx"
|
|
254
|
-
import { useLocale } from "react-intlayer";
|
|
255
256
|
import { useNavigate } from "@tanstack/react-router";
|
|
257
|
+
import { getPrefix } from "intlayer";
|
|
258
|
+
import { useLocale } from "react-intlayer";
|
|
256
259
|
import { LOCALE_ROUTE } from "@/components/localized-link";
|
|
257
260
|
import type { FileRouteTypes } from "@/routeTree.gen";
|
|
258
261
|
|
|
262
|
+
type StripLocalePrefix<T extends string> = T extends
|
|
263
|
+
| `/${typeof LOCALE_ROUTE}`
|
|
264
|
+
| `/${typeof LOCALE_ROUTE}/`
|
|
265
|
+
? "/"
|
|
266
|
+
: T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`
|
|
267
|
+
? `/${Rest}`
|
|
268
|
+
: never;
|
|
269
|
+
|
|
270
|
+
type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;
|
|
271
|
+
|
|
272
|
+
type LocalizedNavigate = {
|
|
273
|
+
(to: LocalizedTo): ReturnType<ReturnType<typeof useNavigate>>;
|
|
274
|
+
(
|
|
275
|
+
opts: { to: LocalizedTo } & Record<string, unknown>
|
|
276
|
+
): ReturnType<ReturnType<typeof useNavigate>>;
|
|
277
|
+
};
|
|
278
|
+
|
|
259
279
|
export const useLocalizedNavigate = () => {
|
|
260
280
|
const navigate = useNavigate();
|
|
261
281
|
|
|
262
282
|
const { locale } = useLocale();
|
|
263
283
|
|
|
264
|
-
type StripLocalePrefix<T extends string> = T extends
|
|
265
|
-
| `/${typeof LOCALE_ROUTE}`
|
|
266
|
-
| `/${typeof LOCALE_ROUTE}/`
|
|
267
|
-
? "/"
|
|
268
|
-
: T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`
|
|
269
|
-
? `/${Rest}`
|
|
270
|
-
: never;
|
|
271
|
-
|
|
272
|
-
type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;
|
|
273
|
-
|
|
274
|
-
interface LocalizedNavigate {
|
|
275
|
-
(to: LocalizedTo): ReturnType<typeof navigate>;
|
|
276
|
-
(
|
|
277
|
-
opts: { to: LocalizedTo } & Record<string, unknown>
|
|
278
|
-
): ReturnType<typeof navigate>;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
284
|
const localizedNavigate: LocalizedNavigate = (args: any) => {
|
|
285
|
+
const { localePrefix } = getPrefix(locale);
|
|
286
|
+
|
|
282
287
|
if (typeof args === "string") {
|
|
283
|
-
return navigate({
|
|
288
|
+
return navigate({
|
|
289
|
+
to: `/${LOCALE_ROUTE}${args}`,
|
|
290
|
+
params: { locale: localePrefix },
|
|
291
|
+
});
|
|
284
292
|
}
|
|
285
293
|
|
|
286
294
|
const { to, ...rest } = args;
|
|
287
295
|
|
|
288
|
-
const
|
|
296
|
+
const localizedTo = `/${LOCALE_ROUTE}${to}` as any;
|
|
289
297
|
|
|
290
|
-
return navigate({
|
|
298
|
+
return navigate({
|
|
299
|
+
to: localizedTo,
|
|
300
|
+
params: { locale: localePrefix, ...rest } as any,
|
|
301
|
+
});
|
|
291
302
|
};
|
|
292
303
|
|
|
293
304
|
return localizedNavigate;
|
|
@@ -361,8 +372,13 @@ function RouteComponent() {
|
|
|
361
372
|
import type { FC } from "react";
|
|
362
373
|
|
|
363
374
|
import { useLocation } from "@tanstack/react-router";
|
|
364
|
-
import {
|
|
365
|
-
|
|
375
|
+
import {
|
|
376
|
+
getHTMLTextDir,
|
|
377
|
+
getLocaleName,
|
|
378
|
+
getPathWithoutLocale,
|
|
379
|
+
getPrefix,
|
|
380
|
+
} from "intlayer";
|
|
381
|
+
import { setLocaleInStorage, useIntlayer, useLocale } from "react-intlayer";
|
|
366
382
|
|
|
367
383
|
import { LocalizedLink, To } from "./localized-link";
|
|
368
384
|
|
|
@@ -381,9 +397,8 @@ export const LocaleSwitcher: FC = () => {
|
|
|
381
397
|
<LocalizedLink
|
|
382
398
|
aria-current={localeEl === locale ? "page" : undefined}
|
|
383
399
|
aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeEl)}`}
|
|
384
|
-
onClick={() =>
|
|
385
|
-
params={{ locale: localeEl }}
|
|
386
|
-
to={pathWithoutLocale as To}
|
|
400
|
+
onClick={() => setLocaleInStorage(localeEl)}
|
|
401
|
+
params={{ locale: getPrefix(localeEl).localePrefix }}
|
|
387
402
|
>
|
|
388
403
|
<span>
|
|
389
404
|
{/* اللغة المحلية - مثل FR */}
|
|
@@ -461,15 +476,15 @@ function LayoutComponent() {
|
|
|
461
476
|
|
|
462
477
|
### الخطوة 11: إضافة الوسيط (اختياري)
|
|
463
478
|
|
|
464
|
-
يمكنك أيضًا استخدام `
|
|
479
|
+
يمكنك أيضًا استخدام `intlayerProxy` لإضافة التوجيه من جانب الخادم إلى تطبيقك. سيقوم هذا الملحق تلقائيًا بالكشف عن اللغة الحالية بناءً على عنوان URL وتعيين ملف تعريف الارتباط الخاص باللغة المناسبة. إذا لم يتم تحديد لغة، فسيحدد الملحق اللغة الأنسب بناءً على تفضيلات لغة متصفح المستخدم. وإذا لم يتم الكشف عن أي لغة، فسيتم إعادة التوجيه إلى اللغة الافتراضية.
|
|
465
480
|
|
|
466
|
-
> لاحظ أنه لاستخدام `
|
|
481
|
+
> لاحظ أنه لاستخدام `intlayerProxy` في بيئة الإنتاج، تحتاج إلى نقل حزمة `vite-intlayer` من `devDependencies` إلى `dependencies`.
|
|
467
482
|
|
|
468
483
|
```typescript {3,7} fileName="vite.config.ts"
|
|
469
484
|
import { reactRouter } from "@react-router/dev/vite";
|
|
470
485
|
import tailwindcss from "@tailwindcss/vite";
|
|
471
486
|
import { defineConfig } from "vite";
|
|
472
|
-
import { intlayer,
|
|
487
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
473
488
|
import tsconfigPaths from "vite-tsconfig-paths";
|
|
474
489
|
|
|
475
490
|
export default defineConfig({
|
|
@@ -478,7 +493,7 @@ export default defineConfig({
|
|
|
478
493
|
reactRouter(),
|
|
479
494
|
tsconfigPaths(),
|
|
480
495
|
intlayer(),
|
|
481
|
-
|
|
496
|
+
intlayerProxy(),
|
|
482
497
|
],
|
|
483
498
|
});
|
|
484
499
|
```
|
|
@@ -1058,38 +1058,38 @@ const App = () => (
|
|
|
1058
1058
|
module.exports = App;
|
|
1059
1059
|
```
|
|
1060
1060
|
|
|
1061
|
-
بالتوازي، يمكنك أيضًا استخدام `
|
|
1061
|
+
بالتوازي، يمكنك أيضًا استخدام `intlayerProxy` لإضافة التوجيه من جانب الخادم إلى تطبيقك. سيقوم هذا المكون الإضافي تلقائيًا بالكشف عن اللغة الحالية بناءً على عنوان URL وتعيين ملف تعريف الارتباط المناسب للغة. إذا لم يتم تحديد لغة، سيحدد المكون الإضافي اللغة الأنسب بناءً على تفضيلات لغة متصفح المستخدم. إذا لم يتم الكشف عن أي لغة، فسيتم إعادة التوجيه إلى اللغة الافتراضية.
|
|
1062
1062
|
|
|
1063
1063
|
```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
|
|
1064
1064
|
import { defineConfig } from "vite";
|
|
1065
1065
|
import preact from "@preact/preset-vite";
|
|
1066
|
-
import { intlayer,
|
|
1066
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
1067
1067
|
|
|
1068
1068
|
// https://vitejs.dev/config/
|
|
1069
1069
|
export default defineConfig({
|
|
1070
|
-
plugins: [preact(), intlayer(),
|
|
1070
|
+
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1071
1071
|
});
|
|
1072
1072
|
```
|
|
1073
1073
|
|
|
1074
1074
|
```javascript {3,7} fileName="vite.config.mjs" codeFormat="esm"
|
|
1075
1075
|
import { defineConfig } from "vite";
|
|
1076
1076
|
import preact from "@preact/preset-vite";
|
|
1077
|
-
import { intlayer,
|
|
1077
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
1078
1078
|
|
|
1079
1079
|
// https://vitejs.dev/config/
|
|
1080
1080
|
export default defineConfig({
|
|
1081
|
-
plugins: [preact(), intlayer(),
|
|
1081
|
+
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1082
1082
|
});
|
|
1083
1083
|
```
|
|
1084
1084
|
|
|
1085
1085
|
```javascript {3,7} fileName="vite.config.cjs" codeFormat="commonjs"
|
|
1086
1086
|
const { defineConfig } = require("vite");
|
|
1087
1087
|
const preact = require("@preact/preset-vite");
|
|
1088
|
-
const { intlayer,
|
|
1088
|
+
const { intlayer, intlayerProxy } = require("vite-intlayer");
|
|
1089
1089
|
|
|
1090
1090
|
// https://vitejs.dev/config/
|
|
1091
1091
|
module.exports = defineConfig({
|
|
1092
|
-
plugins: [preact(), intlayer(),
|
|
1092
|
+
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1093
1093
|
});
|
|
1094
1094
|
```
|
|
1095
1095
|
|
|
@@ -1017,38 +1017,38 @@ const App = () => (
|
|
|
1017
1017
|
);
|
|
1018
1018
|
```
|
|
1019
1019
|
|
|
1020
|
-
بالتوازي، يمكنك أيضًا استخدام `
|
|
1020
|
+
بالتوازي، يمكنك أيضًا استخدام `intlayerProxy` لإضافة التوجيه من جانب الخادم إلى تطبيقك. سيقوم هذا المكون الإضافي بالكشف تلقائيًا عن اللغة الحالية بناءً على عنوان URL وتعيين ملف تعريف الارتباط المناسب للغة. إذا لم يتم تحديد لغة، فسيحدد المكون الإضافي اللغة الأنسب بناءً على تفضيلات لغة متصفح المستخدم. إذا لم يتم الكشف عن أي لغة، فسيتم إعادة التوجيه إلى اللغة الافتراضية.
|
|
1021
1021
|
|
|
1022
1022
|
```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
|
|
1023
1023
|
import { defineConfig } from "vite";
|
|
1024
1024
|
import react from "@vitejs/plugin-react-swc";
|
|
1025
|
-
import { intlayer,
|
|
1025
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
1026
1026
|
|
|
1027
1027
|
// https://vitejs.dev/config/
|
|
1028
1028
|
export default defineConfig({
|
|
1029
|
-
plugins: [react(), intlayer(),
|
|
1029
|
+
plugins: [react(), intlayer(), intlayerProxy()],
|
|
1030
1030
|
});
|
|
1031
1031
|
```
|
|
1032
1032
|
|
|
1033
1033
|
```javascript {3,7} fileName="vite.config.mjs" codeFormat="esm"
|
|
1034
1034
|
import { defineConfig } from "vite";
|
|
1035
1035
|
import react from "@vitejs/plugin-react-swc";
|
|
1036
|
-
import { intlayer,
|
|
1036
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
1037
1037
|
|
|
1038
1038
|
// https://vitejs.dev/config/
|
|
1039
1039
|
export default defineConfig({
|
|
1040
|
-
plugins: [react(), intlayer(),
|
|
1040
|
+
plugins: [react(), intlayer(), intlayerProxy()],
|
|
1041
1041
|
});
|
|
1042
1042
|
```
|
|
1043
1043
|
|
|
1044
1044
|
```javascript {3,7} fileName="vite.config.cjs" codeFormat="commonjs"
|
|
1045
1045
|
const { defineConfig } = require("vite");
|
|
1046
1046
|
const react = require("@vitejs/plugin-react-swc");
|
|
1047
|
-
const { intlayer,
|
|
1047
|
+
const { intlayer, intlayerProxy } = require("vite-intlayer");
|
|
1048
1048
|
|
|
1049
1049
|
// https://vitejs.dev/config/
|
|
1050
1050
|
module.exports = defineConfig({
|
|
1051
|
-
plugins: [react(), intlayer(),
|
|
1051
|
+
plugins: [react(), intlayer(), intlayerProxy()],
|
|
1052
1052
|
});
|
|
1053
1053
|
```
|
|
1054
1054
|
|
|
@@ -657,46 +657,46 @@ import LocaleSwitcher from "@components/LocaleSwitcher.vue";
|
|
|
657
657
|
</template>
|
|
658
658
|
```
|
|
659
659
|
|
|
660
|
-
بالتوازي، يمكنك أيضًا استخدام `
|
|
660
|
+
بالتوازي، يمكنك أيضًا استخدام `intlayerProxy` لإضافة التوجيه من جانب الخادم إلى تطبيقك. سيقوم هذا المكون الإضافي بالكشف تلقائيًا عن اللغة الحالية بناءً على عنوان URL وتعيين ملف تعريف الارتباط المناسب للغة. إذا لم يتم تحديد لغة، سيحدد المكون الإضافي اللغة الأنسب بناءً على تفضيلات لغة متصفح المستخدم. إذا لم يتم الكشف عن أي لغة، فسيتم إعادة التوجيه إلى اللغة الافتراضية.
|
|
661
661
|
|
|
662
662
|
```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
|
|
663
663
|
import { defineConfig } from "vite";
|
|
664
664
|
import vue from "@vitejs/plugin-vue";
|
|
665
|
-
import { intlayer,
|
|
665
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
666
666
|
|
|
667
667
|
// https://vitejs.dev/config/
|
|
668
668
|
export default defineConfig({
|
|
669
|
-
plugins: [vue(), intlayer(),
|
|
669
|
+
plugins: [vue(), intlayer(), intlayerProxy()],
|
|
670
670
|
});
|
|
671
671
|
```
|
|
672
672
|
|
|
673
673
|
```javascript {3,7} fileName="vite.config.mjs" codeFormat="esm"
|
|
674
674
|
import { defineConfig } from "vite";
|
|
675
675
|
import vue from "@vitejs/plugin-vue";
|
|
676
|
-
import { intlayer,
|
|
676
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
677
677
|
|
|
678
678
|
// https://vitejs.dev/config/
|
|
679
679
|
export default defineConfig({
|
|
680
|
-
plugins: [vue(), intlayer(),
|
|
680
|
+
plugins: [vue(), intlayer(), intlayerProxy()],
|
|
681
681
|
});
|
|
682
682
|
```
|
|
683
683
|
|
|
684
684
|
```javascript {3,7} fileName="vite.config.cjs" codeFormat="commonjs"
|
|
685
685
|
const { defineConfig } = require("vite");
|
|
686
686
|
const vue = require("@vitejs/plugin-vue");
|
|
687
|
-
const { intlayer,
|
|
687
|
+
const { intlayer, intlayerProxy } = require("vite-intlayer");
|
|
688
688
|
|
|
689
689
|
// https://vitejs.dev/config/
|
|
690
690
|
module.exports = defineConfig({
|
|
691
|
-
plugins: [vue(), intlayer(),
|
|
691
|
+
plugins: [vue(), intlayer(), intlayerProxy()],
|
|
692
692
|
});
|
|
693
693
|
const { defineConfig } = require("vite");
|
|
694
694
|
const vue = require("@vitejs/plugin-vue");
|
|
695
|
-
const { intlayer,
|
|
695
|
+
const { intlayer, intlayerProxy } = require("vite-intlayer");
|
|
696
696
|
|
|
697
697
|
// https://vitejs.dev/config/
|
|
698
698
|
module.exports = defineConfig({
|
|
699
|
-
plugins: [vue(), intlayer(),
|
|
699
|
+
plugins: [vue(), intlayer(), intlayerProxy()],
|
|
700
700
|
});
|
|
701
701
|
```
|
|
702
702
|
|
|
@@ -914,8 +914,8 @@ import { type FC } from "react";
|
|
|
914
914
|
import Link from "next/link";
|
|
915
915
|
|
|
916
916
|
const LocaleSwitcher: FC = () => {
|
|
917
|
-
const { locale, pathWithoutLocale, availableLocales } =
|
|
918
|
-
|
|
917
|
+
const { locale, pathWithoutLocale, availableLocales, setLocale } =
|
|
918
|
+
useLocale();
|
|
919
919
|
|
|
920
920
|
return (
|
|
921
921
|
<div>
|
|
@@ -927,7 +927,7 @@ const LocaleSwitcher: FC = () => {
|
|
|
927
927
|
hrefLang={localeItem}
|
|
928
928
|
key={localeItem}
|
|
929
929
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
930
|
-
onClick={() =>
|
|
930
|
+
onClick={() => setLocale(localeItem)}
|
|
931
931
|
>
|
|
932
932
|
<span>
|
|
933
933
|
{/* Sprache - z. B. FR */}
|
|
@@ -966,8 +966,8 @@ import { useLocale } from "next-intlayer";
|
|
|
966
966
|
import Link from "next/link";
|
|
967
967
|
|
|
968
968
|
const LocaleSwitcher = () => {
|
|
969
|
-
const { locale, pathWithoutLocale, availableLocales } =
|
|
970
|
-
|
|
969
|
+
const { locale, pathWithoutLocale, availableLocales, setLocale } =
|
|
970
|
+
useLocale();
|
|
971
971
|
|
|
972
972
|
return (
|
|
973
973
|
<div>
|
|
@@ -979,7 +979,7 @@ const LocaleSwitcher = () => {
|
|
|
979
979
|
hrefLang={localeItem}
|
|
980
980
|
key={localeItem}
|
|
981
981
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
982
|
-
onClick={() =>
|
|
982
|
+
onClick={() => setLocale(localeItem)}
|
|
983
983
|
>
|
|
984
984
|
<span>
|
|
985
985
|
{/* Sprache - z. B. FR */}
|
|
@@ -1018,8 +1018,8 @@ const { useLocale } = require("next-intlayer");
|
|
|
1018
1018
|
const Link = require("next/link");
|
|
1019
1019
|
|
|
1020
1020
|
const LocaleSwitcher = () => {
|
|
1021
|
-
const { locale, pathWithoutLocale, availableLocales } =
|
|
1022
|
-
|
|
1021
|
+
const { locale, pathWithoutLocale, availableLocales, setLocale } =
|
|
1022
|
+
useLocale();
|
|
1023
1023
|
|
|
1024
1024
|
return (
|
|
1025
1025
|
<div>
|
|
@@ -1031,7 +1031,7 @@ const LocaleSwitcher = () => {
|
|
|
1031
1031
|
hrefLang={localeItem}
|
|
1032
1032
|
key={localeItem}
|
|
1033
1033
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1034
|
-
onClick={() =>
|
|
1034
|
+
onClick={() => setLocale(localeItem)}
|
|
1035
1035
|
>
|
|
1036
1036
|
<span>
|
|
1037
1037
|
{/* Sprache - z. B. FR */}
|
|
@@ -1158,8 +1158,8 @@ import { useLocale } from "next-intlayer";
|
|
|
1158
1158
|
import Link from "next/link";
|
|
1159
1159
|
|
|
1160
1160
|
export const LocaleSwitcher: FC = () => {
|
|
1161
|
-
const { locale, pathWithoutLocale, availableLocales } =
|
|
1162
|
-
|
|
1161
|
+
const { locale, pathWithoutLocale, availableLocales, setLocale } =
|
|
1162
|
+
useLocale();
|
|
1163
1163
|
|
|
1164
1164
|
return (
|
|
1165
1165
|
<div>
|
|
@@ -1171,7 +1171,7 @@ export const LocaleSwitcher: FC = () => {
|
|
|
1171
1171
|
hrefLang={localeItem}
|
|
1172
1172
|
key={localeItem}
|
|
1173
1173
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1174
|
-
onClick={() =>
|
|
1174
|
+
onClick={() => setLocale(localeItem)}
|
|
1175
1175
|
>
|
|
1176
1176
|
<span>
|
|
1177
1177
|
{/* Gebietsschema - z.B. FR */}
|
|
@@ -1210,8 +1210,8 @@ import { useLocale } from "next-intlayer";
|
|
|
1210
1210
|
import Link from "next/link";
|
|
1211
1211
|
|
|
1212
1212
|
export const LocaleSwitcher = () => {
|
|
1213
|
-
const { locale, pathWithoutLocale, availableLocales } =
|
|
1214
|
-
|
|
1213
|
+
const { locale, pathWithoutLocale, availableLocales, setLocale } =
|
|
1214
|
+
useLocale();
|
|
1215
1215
|
|
|
1216
1216
|
return (
|
|
1217
1217
|
<div>
|
|
@@ -1223,7 +1223,7 @@ export const LocaleSwitcher = () => {
|
|
|
1223
1223
|
hrefLang={localeItem}
|
|
1224
1224
|
key={localeItem}
|
|
1225
1225
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1226
|
-
onClick={() =>
|
|
1226
|
+
onClick={() => setLocale(localeItem)}
|
|
1227
1227
|
>
|
|
1228
1228
|
<span>
|
|
1229
1229
|
{/* Gebietsschema - z.B. FR */}
|
|
@@ -1262,7 +1262,8 @@ const { useLocale } = require("next-intlayer");
|
|
|
1262
1262
|
const Link = require("next/link");
|
|
1263
1263
|
|
|
1264
1264
|
export const LocaleSwitcher = () => {
|
|
1265
|
-
const { locale, pathWithoutLocale, availableLocales } =
|
|
1265
|
+
const { locale, pathWithoutLocale, availableLocales, setLocale } =
|
|
1266
|
+
useLocale();
|
|
1266
1267
|
|
|
1267
1268
|
return (
|
|
1268
1269
|
<div>
|
|
@@ -1274,7 +1275,7 @@ export const LocaleSwitcher = () => {
|
|
|
1274
1275
|
hrefLang={localeItem}
|
|
1275
1276
|
key={localeItem}
|
|
1276
1277
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1277
|
-
onClick={() =>
|
|
1278
|
+
onClick={() => setLocale(localeItem)}
|
|
1278
1279
|
>
|
|
1279
1280
|
<span>
|
|
1280
1281
|
{/* Gebietsschema - z.B. FR */}
|
|
@@ -151,7 +151,7 @@ export default withIntlayer(nextConfig);
|
|
|
151
151
|
Richten Sie Middleware ein, um die bevorzugte Sprache des Benutzers automatisch zu erkennen und zu verarbeiten:
|
|
152
152
|
|
|
153
153
|
```typescript fileName="src/middleware.ts" codeFormat="typescript"
|
|
154
|
-
export {
|
|
154
|
+
export { intlayerProxy as middleware } from "next-intlayer/middleware";
|
|
155
155
|
|
|
156
156
|
export const config = {
|
|
157
157
|
matcher:
|
|
@@ -160,7 +160,7 @@ export const config = {
|
|
|
160
160
|
```
|
|
161
161
|
|
|
162
162
|
```javascript fileName="src/middleware.mjs" codeFormat="esm"
|
|
163
|
-
export {
|
|
163
|
+
export { intlayerProxy as middleware } from "next-intlayer/middleware";
|
|
164
164
|
|
|
165
165
|
export const config = {
|
|
166
166
|
matcher:
|
|
@@ -169,14 +169,14 @@ export const config = {
|
|
|
169
169
|
```
|
|
170
170
|
|
|
171
171
|
```javascript fileName="src/middleware.cjs" codeFormat="commonjs"
|
|
172
|
-
const {
|
|
172
|
+
const { intlayerProxy } = require("next-intlayer/middleware");
|
|
173
173
|
|
|
174
174
|
const config = {
|
|
175
175
|
matcher:
|
|
176
176
|
"/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
|
|
177
177
|
};
|
|
178
178
|
|
|
179
|
-
module.exports = { middleware:
|
|
179
|
+
module.exports = { middleware: intlayerProxy, config };
|
|
180
180
|
```
|
|
181
181
|
|
|
182
182
|
> Passen Sie den Parameter `matcher` an, um die Routen Ihrer Anwendung abzudecken. Weitere Details finden Sie in der [Next.js-Dokumentation zur Konfiguration des Matchers](https://nextjs.org/docs/app/building-your-application/routing/middleware).
|
|
@@ -1097,7 +1097,6 @@ import Link from "next/link";
|
|
|
1097
1097
|
|
|
1098
1098
|
const LocaleSwitcher: FC = () => {
|
|
1099
1099
|
const { locale, pathWithoutLocale, availableLocales } = useLocalePageRouter();
|
|
1100
|
-
const { setLocaleCookie } = useLocaleCookie();
|
|
1101
1100
|
|
|
1102
1101
|
return (
|
|
1103
1102
|
<div>
|
|
@@ -1109,7 +1108,7 @@ const LocaleSwitcher: FC = () => {
|
|
|
1109
1108
|
hrefLang={localeItem}
|
|
1110
1109
|
key={localeItem}
|
|
1111
1110
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1112
|
-
onClick={() =>
|
|
1111
|
+
onClick={() => setLocale(localeItem)}
|
|
1113
1112
|
>
|
|
1114
1113
|
<span>
|
|
1115
1114
|
{/* Gebietsschema - z.B. FR */}
|
|
@@ -1147,7 +1146,6 @@ import Link from "next/link";
|
|
|
1147
1146
|
|
|
1148
1147
|
const LocaleSwitcher = () => {
|
|
1149
1148
|
const { locale, pathWithoutLocale, availableLocales } = useLocalePageRouter();
|
|
1150
|
-
const { setLocaleCookie } = useLocaleCookie();
|
|
1151
1149
|
|
|
1152
1150
|
return (
|
|
1153
1151
|
<div>
|
|
@@ -1159,7 +1157,7 @@ const LocaleSwitcher = () => {
|
|
|
1159
1157
|
hrefLang={localeItem}
|
|
1160
1158
|
key={localeItem}
|
|
1161
1159
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1162
|
-
onClick={() =>
|
|
1160
|
+
onClick={() => setLocale(localeItem)}
|
|
1163
1161
|
>
|
|
1164
1162
|
<span>
|
|
1165
1163
|
{/* Gebietsschema - z.B. FR */}
|
|
@@ -1197,7 +1195,6 @@ const Link = require("next/link");
|
|
|
1197
1195
|
|
|
1198
1196
|
const LocaleSwitcher = () => {
|
|
1199
1197
|
const { locale, pathWithoutLocale, availableLocales } = useLocalePageRouter();
|
|
1200
|
-
const { setLocaleCookie } = useLocaleCookie();
|
|
1201
1198
|
|
|
1202
1199
|
return (
|
|
1203
1200
|
<select>
|
|
@@ -1207,7 +1204,7 @@ const LocaleSwitcher = () => {
|
|
|
1207
1204
|
href={getLocalizedUrl(pathWithoutLocale, localeItem)}
|
|
1208
1205
|
hrefLang={localeItem}
|
|
1209
1206
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1210
|
-
onClick={() =>
|
|
1207
|
+
onClick={() => setLocale(localeItem)}
|
|
1211
1208
|
>
|
|
1212
1209
|
<span>
|
|
1213
1210
|
{/* Gebietsschema - z.B. FR */}
|
|
@@ -318,7 +318,7 @@ import {
|
|
|
318
318
|
getLocalizedUrl,
|
|
319
319
|
getPathWithoutLocale,
|
|
320
320
|
} from "intlayer";
|
|
321
|
-
import {
|
|
321
|
+
import { setLocaleInStorage, useIntlayer, useLocale } from "react-intlayer";
|
|
322
322
|
import { Link, useLocation } from "react-router";
|
|
323
323
|
|
|
324
324
|
export const LocaleSwitcher: FC = () => {
|
|
@@ -336,7 +336,7 @@ export const LocaleSwitcher: FC = () => {
|
|
|
336
336
|
<Link
|
|
337
337
|
aria-current={localeItem === locale ? "page" : undefined}
|
|
338
338
|
aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeItem)}`}
|
|
339
|
-
onClick={() =>
|
|
339
|
+
onClick={() => setLocale(localeItem)}
|
|
340
340
|
to={getLocalizedUrl(pathWithoutLocale, localeItem)}
|
|
341
341
|
>
|
|
342
342
|
<span>
|
|
@@ -405,18 +405,18 @@ export default function RootLayout() {
|
|
|
405
405
|
|
|
406
406
|
### Schritt 11: Middleware hinzufügen (Optional)
|
|
407
407
|
|
|
408
|
-
Sie können auch das `
|
|
408
|
+
Sie können auch das `intlayerProxy` verwenden, um serverseitiges Routing zu Ihrer Anwendung hinzuzufügen. Dieses Plugin erkennt automatisch die aktuelle Locale basierend auf der URL und setzt das entsprechende Locale-Cookie. Wenn keine Locale angegeben ist, bestimmt das Plugin die am besten geeignete Locale basierend auf den Spracheinstellungen des Browsers des Benutzers. Wenn keine Locale erkannt wird, erfolgt eine Weiterleitung zur Standard-Locale.
|
|
409
409
|
|
|
410
|
-
> Beachten Sie, dass Sie, um das `
|
|
410
|
+
> Beachten Sie, dass Sie, um das `intlayerProxy` in der Produktion zu verwenden, das Paket `vite-intlayer` von `devDependencies` zu `dependencies` verschieben müssen.
|
|
411
411
|
|
|
412
412
|
```typescript {3,7} fileName="vite.config.ts"
|
|
413
413
|
import { defineConfig } from "vite";
|
|
414
414
|
import react from "@vitejs/plugin-react-swc";
|
|
415
|
-
import { intlayer,
|
|
415
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
416
416
|
|
|
417
417
|
// https://vitejs.dev/config/
|
|
418
418
|
export default defineConfig({
|
|
419
|
-
plugins: [react(), intlayer(),
|
|
419
|
+
plugins: [react(), intlayer(), intlayerProxy()],
|
|
420
420
|
});
|
|
421
421
|
```
|
|
422
422
|
|