@intlayer/docs 7.3.8 → 7.3.9
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/docs/ar/intlayer_with_tanstack.md +52 -1
- package/docs/ar/intlayer_with_vite+vue.md +16 -34
- package/docs/de/intlayer_with_tanstack.md +52 -1
- package/docs/de/intlayer_with_vite+vue.md +16 -34
- package/docs/en/intlayer_with_tanstack.md +52 -1
- package/docs/en/intlayer_with_vite+vue.md +16 -34
- package/docs/en-GB/intlayer_with_tanstack.md +52 -1
- package/docs/en-GB/intlayer_with_vite+vue.md +16 -34
- package/docs/es/intlayer_with_tanstack.md +52 -1
- package/docs/es/intlayer_with_vite+vue.md +16 -34
- package/docs/fr/intlayer_with_tanstack.md +52 -1
- package/docs/fr/intlayer_with_vite+vue.md +16 -34
- package/docs/hi/intlayer_with_tanstack.md +52 -1
- package/docs/hi/intlayer_with_vite+vue.md +16 -34
- package/docs/id/intlayer_with_tanstack.md +52 -1
- package/docs/id/intlayer_with_vite+vue.md +16 -34
- package/docs/it/intlayer_with_tanstack.md +52 -1
- package/docs/it/intlayer_with_vite+vue.md +16 -34
- package/docs/ja/intlayer_with_tanstack.md +52 -1
- package/docs/ja/intlayer_with_vite+vue.md +16 -34
- package/docs/ko/intlayer_with_tanstack.md +52 -1
- package/docs/ko/intlayer_with_vite+vue.md +16 -34
- package/docs/pl/intlayer_with_tanstack.md +52 -1
- package/docs/pl/intlayer_with_vite+vue.md +16 -34
- package/docs/pt/intlayer_with_tanstack.md +52 -1
- package/docs/pt/intlayer_with_vite+vue.md +16 -34
- package/docs/ru/intlayer_with_tanstack.md +52 -1
- package/docs/ru/intlayer_with_vite+vue.md +16 -34
- package/docs/tr/intlayer_with_tanstack.md +52 -1
- package/docs/tr/intlayer_with_vite+vue.md +16 -34
- package/docs/vi/intlayer_with_tanstack.md +52 -1
- package/docs/vi/intlayer_with_vite+vue.md +16 -34
- package/docs/zh/intlayer_with_tanstack.md +52 -1
- package/docs/zh/intlayer_with_vite+vue.md +16 -34
- package/package.json +6 -6
|
@@ -18,6 +18,9 @@ slugs:
|
|
|
18
18
|
- tanstack-start
|
|
19
19
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
|
|
20
20
|
history:
|
|
21
|
+
- version: 7.3.9
|
|
22
|
+
date: 2025-12-05
|
|
23
|
+
changes: Add step 13: Retrieve the locale in your server actions (Optional)
|
|
21
24
|
- version: 5.8.1
|
|
22
25
|
date: 2025-09-09
|
|
23
26
|
changes: أضيف لـ Tanstack Start
|
|
@@ -537,7 +540,55 @@ export const Route = createFileRoute("/{-$locale}/")({
|
|
|
537
540
|
|
|
538
541
|
---
|
|
539
542
|
|
|
540
|
-
###
|
|
543
|
+
### Step 13: Retrieve the locale in your server actions (Optional)
|
|
544
|
+
|
|
545
|
+
You may want to access the current locale from inside your server actions or API endpoints.
|
|
546
|
+
You can do this using the `getLocale` helper from `intlayer`.
|
|
547
|
+
|
|
548
|
+
Here's an example using TanStack Start's server functions:
|
|
549
|
+
|
|
550
|
+
```tsx fileName="src/routes/{-$locale}/index.tsx"
|
|
551
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
552
|
+
import {
|
|
553
|
+
getRequestHeader,
|
|
554
|
+
getRequestHeaders,
|
|
555
|
+
} from "@tanstack/react-start/server";
|
|
556
|
+
import { getCookie, getIntlayer, getLocale } from "intlayer";
|
|
557
|
+
|
|
558
|
+
export const getLocaleServer = createServerFn().handler(async () => {
|
|
559
|
+
const locale = await getLocale({
|
|
560
|
+
// Get the cookie from the request (default: 'INTLAYER_LOCALE')
|
|
561
|
+
getCookie: (name) => {
|
|
562
|
+
const cookieString = getRequestHeader("cookie");
|
|
563
|
+
|
|
564
|
+
return getCookie(name, cookieString);
|
|
565
|
+
},
|
|
566
|
+
// Get the header from the request (default: 'x-intlayer-locale')
|
|
567
|
+
getHeader: (name) => getRequestHeader(name),
|
|
568
|
+
// Fallback using Accept-Language negotiation
|
|
569
|
+
getAllHeaders: async () => {
|
|
570
|
+
const headers = getRequestHeaders();
|
|
571
|
+
const result: Record<string, string> = {};
|
|
572
|
+
|
|
573
|
+
// Convert the TypedHeaders into a plain Record<string, string>
|
|
574
|
+
for (const [key, value] of headers.entries()) {
|
|
575
|
+
result[key] = value;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
return result;
|
|
579
|
+
},
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
// Retrieve some content using getIntlayer()
|
|
583
|
+
const content = getIntlayer("app", locale);
|
|
584
|
+
|
|
585
|
+
return { locale, content };
|
|
586
|
+
});
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
### الخطوة 14: تكوين TypeScript (اختياري)
|
|
541
592
|
|
|
542
593
|
يستخدم Intlayer توسيع الوحدات (module augmentation) للاستفادة من TypeScript وجعل قاعدة الشيفرة الخاصة بك أقوى.
|
|
543
594
|
|
|
@@ -542,53 +542,47 @@ const content = useIntlayer("app"); // أنشئ ملف إعلان intlayer ال
|
|
|
542
542
|
أولاً، قم بتثبيت Vue Router:
|
|
543
543
|
|
|
544
544
|
```bash packageManager="npm"
|
|
545
|
-
npm install
|
|
545
|
+
npm install vue-router
|
|
546
546
|
```
|
|
547
547
|
|
|
548
548
|
```bash packageManager="pnpm"
|
|
549
|
-
pnpm add
|
|
549
|
+
pnpm add vue-router
|
|
550
550
|
```
|
|
551
551
|
|
|
552
552
|
```bash packageManager="yarn"
|
|
553
|
-
yarn add
|
|
553
|
+
yarn add vue-router
|
|
554
554
|
```
|
|
555
555
|
|
|
556
556
|
ثم، قم بإنشاء تكوين جهاز التوجيه الذي يتعامل مع التوجيه بناءً على اللغة:
|
|
557
557
|
|
|
558
558
|
```js fileName="src/router/index.ts"
|
|
559
559
|
import {
|
|
560
|
-
configuration,
|
|
561
|
-
getPathWithoutLocale,
|
|
562
560
|
localeFlatMap,
|
|
563
|
-
type
|
|
561
|
+
type Locale,
|
|
564
562
|
} from 'intlayer';
|
|
565
563
|
import { createIntlayerClient } from 'vue-intlayer';
|
|
566
564
|
import { createRouter, createWebHistory } from 'vue-router';
|
|
567
565
|
import HomeView from './views/home/HomeView.vue';
|
|
568
566
|
import RootView from './views/root/Root.vue';
|
|
569
567
|
|
|
570
|
-
// الحصول على إعدادات التدويل
|
|
571
|
-
const { internationalization, middleware } = configuration;
|
|
572
|
-
const { defaultLocale } = internationalization;
|
|
573
|
-
|
|
574
568
|
/**
|
|
575
569
|
* إعلان المسارات مع مسارات وبيانات وصفية خاصة بكل لغة.
|
|
576
570
|
*/
|
|
577
|
-
const routes = localeFlatMap((
|
|
571
|
+
const routes = localeFlatMap(({ urlPrefix, locale }) => [
|
|
578
572
|
{
|
|
579
|
-
path: `${
|
|
580
|
-
name: `Root-${
|
|
573
|
+
path: `${urlPrefix}/`,
|
|
574
|
+
name: `Root-${locale}`,
|
|
581
575
|
component: RootView,
|
|
582
576
|
meta: {
|
|
583
|
-
locale
|
|
577
|
+
locale,
|
|
584
578
|
},
|
|
585
579
|
},
|
|
586
580
|
{
|
|
587
|
-
path: `${
|
|
588
|
-
name: `Home-${
|
|
581
|
+
path: `${urlPrefix}/home`,
|
|
582
|
+
name: `Home-${locale}`,
|
|
589
583
|
component: HomeView,
|
|
590
584
|
meta: {
|
|
591
|
-
locale
|
|
585
|
+
locale,
|
|
592
586
|
},
|
|
593
587
|
},
|
|
594
588
|
]);
|
|
@@ -603,23 +597,11 @@ export const router = createRouter({
|
|
|
603
597
|
router.beforeEach((to, _from, next) => {
|
|
604
598
|
const client = createIntlayerClient();
|
|
605
599
|
|
|
606
|
-
const metaLocale = to.meta.locale as
|
|
600
|
+
const metaLocale = to.meta.locale as Locale;
|
|
607
601
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
next();
|
|
612
|
-
} else {
|
|
613
|
-
// الحالة الافتراضية: لا توجد لغة في البيانات، ربما مسار غير مطابق
|
|
614
|
-
// اختياري: التعامل مع خطأ 404 أو إعادة التوجيه إلى اللغة الافتراضية
|
|
615
|
-
client.setLocale(defaultLocale);
|
|
616
|
-
|
|
617
|
-
if (middleware.prefixDefault) {
|
|
618
|
-
next(`/${defaultLocale}${getPathWithoutLocale(to.path)}`);
|
|
619
|
-
} else {
|
|
620
|
-
next(getPathWithoutLocale(to.path));
|
|
621
|
-
}
|
|
622
|
-
}
|
|
602
|
+
// إعادة استخدام اللغة المعرفة في بيانات الراوتر
|
|
603
|
+
client.setLocale(metaLocale);
|
|
604
|
+
next();
|
|
623
605
|
});
|
|
624
606
|
```
|
|
625
607
|
|
|
@@ -757,7 +739,7 @@ watch(
|
|
|
757
739
|
نصيحة: لتحسين تحسين محركات البحث (SEO) وسهولة الوصول، استخدم الوسوم مثل `<a href="/fr/home" hreflang="fr">` للربط بالصفحات المترجمة، كما هو موضح في الخطوة 10. هذا يسمح لمحركات البحث باكتشاف وفهرسة عناوين URL الخاصة بكل لغة بشكل صحيح. للحفاظ على سلوك تطبيق الصفحة الواحدة (SPA)، يمكنك منع التنقل الافتراضي باستخدام @click.prevent، وتغيير اللغة باستخدام useLocale، والتنقل برمجياً باستخدام Vue Router.
|
|
758
740
|
|
|
759
741
|
```html
|
|
760
|
-
<ol
|
|
742
|
+
<ol>
|
|
761
743
|
<li>
|
|
762
744
|
<a
|
|
763
745
|
hreflang="x-default"
|
|
@@ -18,6 +18,9 @@ slugs:
|
|
|
18
18
|
- tanstack-start
|
|
19
19
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
|
|
20
20
|
history:
|
|
21
|
+
- version: 7.3.9
|
|
22
|
+
date: 2025-12-05
|
|
23
|
+
changes: Add step 13: Retrieve the locale in your server actions (Optional)
|
|
21
24
|
- version: 5.8.1
|
|
22
25
|
date: 2025-09-09
|
|
23
26
|
changes: Hinzugefügt für Tanstack Start
|
|
@@ -541,7 +544,55 @@ export const Route = createFileRoute("/{-$locale}/")({
|
|
|
541
544
|
|
|
542
545
|
---
|
|
543
546
|
|
|
544
|
-
### Schritt 13:
|
|
547
|
+
### Schritt 13: Abrufen der Locale in Ihren Serveraktionen (Optional)
|
|
548
|
+
|
|
549
|
+
Möglicherweise möchten Sie von Ihren Serveraktionen oder API-Endpunkten aus auf die aktuelle Locale zugreifen.
|
|
550
|
+
Sie können dies mit dem Helfer `getLocale` aus `intlayer` tun.
|
|
551
|
+
|
|
552
|
+
Hier ist ein Beispiel mit den Serverfunktionen von TanStack Start:
|
|
553
|
+
|
|
554
|
+
```tsx fileName="src/routes/{-$locale}/index.tsx"
|
|
555
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
556
|
+
import {
|
|
557
|
+
getRequestHeader,
|
|
558
|
+
getRequestHeaders,
|
|
559
|
+
} from "@tanstack/react-start/server";
|
|
560
|
+
import { getCookie, getIntlayer, getLocale } from "intlayer";
|
|
561
|
+
|
|
562
|
+
export const getLocaleServer = createServerFn().handler(async () => {
|
|
563
|
+
const locale = await getLocale({
|
|
564
|
+
// Holen Sie sich das Cookie aus der Anfrage (Standard: 'INTLAYER_LOCALE')
|
|
565
|
+
getCookie: (name) => {
|
|
566
|
+
const cookieString = getRequestHeader("cookie");
|
|
567
|
+
|
|
568
|
+
return getCookie(name, cookieString);
|
|
569
|
+
},
|
|
570
|
+
// Holen Sie sich den Header aus der Anfrage (Standard: 'x-intlayer-locale')
|
|
571
|
+
getHeader: (name) => getRequestHeader(name),
|
|
572
|
+
// Fallback mit Accept-Language-Aushandlung
|
|
573
|
+
getAllHeaders: async () => {
|
|
574
|
+
const headers = getRequestHeaders();
|
|
575
|
+
const result: Record<string, string> = {};
|
|
576
|
+
|
|
577
|
+
// Konvertieren Sie die TypedHeaders in ein einfaches Record<string, string>
|
|
578
|
+
for (const [key, value] of headers.entries()) {
|
|
579
|
+
result[key] = value;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
return result;
|
|
583
|
+
},
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
// Rufen Sie Inhalte mit getIntlayer() ab
|
|
587
|
+
const content = getIntlayer("app", locale);
|
|
588
|
+
|
|
589
|
+
return { locale, content };
|
|
590
|
+
});
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
---
|
|
594
|
+
|
|
595
|
+
### Schritt 14: TypeScript konfigurieren (optional)
|
|
545
596
|
|
|
546
597
|
Intlayer verwendet Module Augmentation, um die Vorteile von TypeScript zu nutzen und Ihren Code robuster zu machen.
|
|
547
598
|
|
|
@@ -587,53 +587,47 @@ Beispiel:
|
|
|
587
587
|
Zuerst installieren Sie Vue Router:
|
|
588
588
|
|
|
589
589
|
```bash packageManager="npm"
|
|
590
|
-
npm install
|
|
590
|
+
npm install vue-router
|
|
591
591
|
```
|
|
592
592
|
|
|
593
593
|
```bash packageManager="pnpm"
|
|
594
|
-
pnpm add
|
|
594
|
+
pnpm add vue-router
|
|
595
595
|
```
|
|
596
596
|
|
|
597
597
|
```bash packageManager="yarn"
|
|
598
|
-
yarn add
|
|
598
|
+
yarn add vue-router
|
|
599
599
|
```
|
|
600
600
|
|
|
601
601
|
Dann erstellen Sie eine Router-Konfiguration, die die sprachspezifische Navigation behandelt:
|
|
602
602
|
|
|
603
603
|
```js fileName="src/router/index.ts"
|
|
604
604
|
import {
|
|
605
|
-
configuration,
|
|
606
|
-
getPathWithoutLocale,
|
|
607
605
|
localeFlatMap,
|
|
608
|
-
type
|
|
606
|
+
type Locale,
|
|
609
607
|
} from 'intlayer';
|
|
610
608
|
import { createIntlayerClient } from 'vue-intlayer';
|
|
611
609
|
import { createRouter, createWebHistory } from 'vue-router';
|
|
612
610
|
import HomeView from './views/home/HomeView.vue';
|
|
613
611
|
import RootView from './views/root/Root.vue';
|
|
614
612
|
|
|
615
|
-
// Holen Sie die Internationalisierungskonfiguration
|
|
616
|
-
const { internationalization, middleware } = configuration;
|
|
617
|
-
const { defaultLocale } = internationalization;
|
|
618
|
-
|
|
619
613
|
/**
|
|
620
614
|
* Deklarieren Sie die Routen mit sprachspezifischen Pfaden und Metadaten.
|
|
621
615
|
*/
|
|
622
|
-
const routes = localeFlatMap((
|
|
616
|
+
const routes = localeFlatMap(({ urlPrefix, locale }) => [
|
|
623
617
|
{
|
|
624
|
-
path: `${
|
|
625
|
-
name: `Root-${
|
|
618
|
+
path: `${urlPrefix}/`,
|
|
619
|
+
name: `Root-${locale}`,
|
|
626
620
|
component: RootView,
|
|
627
621
|
meta: {
|
|
628
|
-
locale
|
|
622
|
+
locale,
|
|
629
623
|
},
|
|
630
624
|
},
|
|
631
625
|
{
|
|
632
|
-
path: `${
|
|
633
|
-
name: `Home-${
|
|
626
|
+
path: `${urlPrefix}/home`,
|
|
627
|
+
name: `Home-${locale}`,
|
|
634
628
|
component: HomeView,
|
|
635
629
|
meta: {
|
|
636
|
-
locale
|
|
630
|
+
locale,
|
|
637
631
|
},
|
|
638
632
|
},
|
|
639
633
|
]);
|
|
@@ -648,23 +642,11 @@ export const router = createRouter({
|
|
|
648
642
|
router.beforeEach((to, _from, next) => {
|
|
649
643
|
const client = createIntlayerClient();
|
|
650
644
|
|
|
651
|
-
const metaLocale = to.meta.locale as
|
|
645
|
+
const metaLocale = to.meta.locale as Locale;
|
|
652
646
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
next();
|
|
657
|
-
} else {
|
|
658
|
-
// Fallback: keine Sprache in Meta, möglicherweise keine passende Route
|
|
659
|
-
// Optional: Behandle 404 oder leite zur Standard-Sprache weiter
|
|
660
|
-
client.setLocale(defaultLocale);
|
|
661
|
-
|
|
662
|
-
if (middleware.prefixDefault) {
|
|
663
|
-
next(`/${defaultLocale}${getPathWithoutLocale(to.path)}`);
|
|
664
|
-
} else {
|
|
665
|
-
next(getPathWithoutLocale(to.path));
|
|
666
|
-
}
|
|
667
|
-
}
|
|
647
|
+
// Verwende die in den Routen-Meta definierten Sprache wieder
|
|
648
|
+
client.setLocale(metaLocale);
|
|
649
|
+
next();
|
|
668
650
|
});
|
|
669
651
|
```
|
|
670
652
|
|
|
@@ -802,7 +784,7 @@ watch(
|
|
|
802
784
|
Tipp: Für eine bessere SEO und Barrierefreiheit verwenden Sie Tags wie `<a href="/fr/home" hreflang="fr">`, um auf lokalisierte Seiten zu verlinken, wie in Schritt 10 gezeigt. Dies ermöglicht Suchmaschinen, sprachspezifische URLs korrekt zu entdecken und zu indexieren. Um das SPA-Verhalten beizubehalten, können Sie die Standardnavigation mit @click.prevent verhindern, die Sprache mit useLocale ändern und programmgesteuert mit Vue Router navigieren.
|
|
803
785
|
|
|
804
786
|
```html
|
|
805
|
-
<ol
|
|
787
|
+
<ol>
|
|
806
788
|
<li>
|
|
807
789
|
<a
|
|
808
790
|
hreflang="x-default"
|
|
@@ -18,6 +18,9 @@ slugs:
|
|
|
18
18
|
- tanstack-start
|
|
19
19
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
|
|
20
20
|
history:
|
|
21
|
+
- version: 7.3.9
|
|
22
|
+
date: 2025-12-05
|
|
23
|
+
changes: Add step 13: Retrieve the locale in your server actions (Optional)
|
|
21
24
|
- version: 7.2.3
|
|
22
25
|
date: 2025-11-18
|
|
23
26
|
changes: Add step 13: Adapt Nitro
|
|
@@ -559,7 +562,55 @@ export const Route = createFileRoute("/{-$locale}/")({
|
|
|
559
562
|
|
|
560
563
|
---
|
|
561
564
|
|
|
562
|
-
### Step 13:
|
|
565
|
+
### Step 13: Retrieve the locale in your server actions (Optional)
|
|
566
|
+
|
|
567
|
+
You may want to access the current locale from inside your server actions or API endpoints.
|
|
568
|
+
You can do this using the `getLocale` helper from `intlayer`.
|
|
569
|
+
|
|
570
|
+
Here's an example using TanStack Start's server functions:
|
|
571
|
+
|
|
572
|
+
```tsx fileName="src/routes/{-$locale}/index.tsx"
|
|
573
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
574
|
+
import {
|
|
575
|
+
getRequestHeader,
|
|
576
|
+
getRequestHeaders,
|
|
577
|
+
} from "@tanstack/react-start/server";
|
|
578
|
+
import { getCookie, getIntlayer, getLocale } from "intlayer";
|
|
579
|
+
|
|
580
|
+
export const getLocaleServer = createServerFn().handler(async () => {
|
|
581
|
+
const locale = await getLocale({
|
|
582
|
+
// Get the cookie from the request (default: 'INTLAYER_LOCALE')
|
|
583
|
+
getCookie: (name) => {
|
|
584
|
+
const cookieString = getRequestHeader("cookie");
|
|
585
|
+
|
|
586
|
+
return getCookie(name, cookieString);
|
|
587
|
+
},
|
|
588
|
+
// Get the header from the request (default: 'x-intlayer-locale')
|
|
589
|
+
getHeader: (name) => getRequestHeader(name),
|
|
590
|
+
// Fallback using Accept-Language negotiation
|
|
591
|
+
getAllHeaders: async () => {
|
|
592
|
+
const headers = getRequestHeaders();
|
|
593
|
+
const result: Record<string, string> = {};
|
|
594
|
+
|
|
595
|
+
// Convert the TypedHeaders into a plain Record<string, string>
|
|
596
|
+
for (const [key, value] of headers.entries()) {
|
|
597
|
+
result[key] = value;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
return result;
|
|
601
|
+
},
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
// Retrieve some content using getIntlayer()
|
|
605
|
+
const content = getIntlayer("app", locale);
|
|
606
|
+
|
|
607
|
+
return { locale, content };
|
|
608
|
+
});
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
---
|
|
612
|
+
|
|
613
|
+
### Step 14: Configure TypeScript (Optional)
|
|
563
614
|
|
|
564
615
|
Intlayer uses module augmentation to get benefits of TypeScript and make your codebase stronger.
|
|
565
616
|
|
|
@@ -546,53 +546,47 @@ Example:
|
|
|
546
546
|
First, install Vue Router:
|
|
547
547
|
|
|
548
548
|
```bash packageManager="npm"
|
|
549
|
-
npm install
|
|
549
|
+
npm install vue-router
|
|
550
550
|
```
|
|
551
551
|
|
|
552
552
|
```bash packageManager="pnpm"
|
|
553
|
-
pnpm add
|
|
553
|
+
pnpm add vue-router
|
|
554
554
|
```
|
|
555
555
|
|
|
556
556
|
```bash packageManager="yarn"
|
|
557
|
-
yarn add
|
|
557
|
+
yarn add vue-router
|
|
558
558
|
```
|
|
559
559
|
|
|
560
560
|
Then, create a router configuration that handles locale-based routing:
|
|
561
561
|
|
|
562
562
|
```js fileName="src/router/index.ts"
|
|
563
563
|
import {
|
|
564
|
-
configuration,
|
|
565
|
-
getPathWithoutLocale,
|
|
566
564
|
localeFlatMap,
|
|
567
|
-
type
|
|
565
|
+
type Locale,
|
|
568
566
|
} from 'intlayer';
|
|
569
567
|
import { createIntlayerClient } from 'vue-intlayer';
|
|
570
568
|
import { createRouter, createWebHistory } from 'vue-router';
|
|
571
569
|
import HomeView from './views/home/HomeView.vue';
|
|
572
570
|
import RootView from './views/root/Root.vue';
|
|
573
571
|
|
|
574
|
-
// Get internationalization configuration
|
|
575
|
-
const { internationalization, middleware } = configuration;
|
|
576
|
-
const { defaultLocale } = internationalization;
|
|
577
|
-
|
|
578
572
|
/**
|
|
579
573
|
* Declare the routes with locale-specific paths and metadata.
|
|
580
574
|
*/
|
|
581
|
-
const routes = localeFlatMap((
|
|
575
|
+
const routes = localeFlatMap(({ urlPrefix, locale }) => [
|
|
582
576
|
{
|
|
583
|
-
path: `${
|
|
584
|
-
name: `Root-${
|
|
577
|
+
path: `${urlPrefix}/`,
|
|
578
|
+
name: `Root-${locale}`,
|
|
585
579
|
component: RootView,
|
|
586
580
|
meta: {
|
|
587
|
-
locale
|
|
581
|
+
locale,
|
|
588
582
|
},
|
|
589
583
|
},
|
|
590
584
|
{
|
|
591
|
-
path: `${
|
|
592
|
-
name: `Home-${
|
|
585
|
+
path: `${urlPrefix}/home`,
|
|
586
|
+
name: `Home-${locale}`,
|
|
593
587
|
component: HomeView,
|
|
594
588
|
meta: {
|
|
595
|
-
locale
|
|
589
|
+
locale,
|
|
596
590
|
},
|
|
597
591
|
},
|
|
598
592
|
]);
|
|
@@ -607,23 +601,11 @@ export const router = createRouter({
|
|
|
607
601
|
router.beforeEach((to, _from, next) => {
|
|
608
602
|
const client = createIntlayerClient();
|
|
609
603
|
|
|
610
|
-
const metaLocale = to.meta.locale as
|
|
604
|
+
const metaLocale = to.meta.locale as Locale;
|
|
611
605
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
next();
|
|
616
|
-
} else {
|
|
617
|
-
// Fallback: no locale in meta, possibly unmatched route
|
|
618
|
-
// Optional: handle 404 or redirect to default locale
|
|
619
|
-
client.setLocale(defaultLocale);
|
|
620
|
-
|
|
621
|
-
if (middleware.prefixDefault) {
|
|
622
|
-
next(`/${defaultLocale}${getPathWithoutLocale(to.path)}`);
|
|
623
|
-
} else {
|
|
624
|
-
next(getPathWithoutLocale(to.path));
|
|
625
|
-
}
|
|
626
|
-
}
|
|
606
|
+
// Reuse the locale defined in the route meta
|
|
607
|
+
client.setLocale(metaLocale);
|
|
608
|
+
next();
|
|
627
609
|
});
|
|
628
610
|
```
|
|
629
611
|
|
|
@@ -755,7 +737,7 @@ watch(
|
|
|
755
737
|
Tip: For better SEO and accessibility, use tags as `<a href="/fr/home" hreflang="fr">` to link to localized pages, as shown in Step 10. This allows search engines to discover and index language-specific URLs properly. To preserve SPA behavior, you can prevent the default navigation with @click.prevent, change the locale using useLocale, and programmatically navigate using Vue Router.
|
|
756
738
|
|
|
757
739
|
```html
|
|
758
|
-
<ol
|
|
740
|
+
<ol>
|
|
759
741
|
<li>
|
|
760
742
|
<a
|
|
761
743
|
hreflang="x-default"
|
|
@@ -18,6 +18,9 @@ slugs:
|
|
|
18
18
|
- tanstack-start
|
|
19
19
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
|
|
20
20
|
history:
|
|
21
|
+
- version: 7.3.9
|
|
22
|
+
date: 2025-12-05
|
|
23
|
+
changes: Add step 13: Retrieve the locale in your server actions (Optional)
|
|
21
24
|
- version: 6.5.2
|
|
22
25
|
date: 2025-10-03
|
|
23
26
|
changes: Update doc
|
|
@@ -540,7 +543,55 @@ export const Route = createFileRoute("/{-$locale}/")({
|
|
|
540
543
|
|
|
541
544
|
---
|
|
542
545
|
|
|
543
|
-
### Step 13:
|
|
546
|
+
### Step 13: Retrieve the locale in your server actions (Optional)
|
|
547
|
+
|
|
548
|
+
You may want to access the current locale from inside your server actions or API endpoints.
|
|
549
|
+
You can do this using the `getLocale` helper from `intlayer`.
|
|
550
|
+
|
|
551
|
+
Here's an example using TanStack Start's server functions:
|
|
552
|
+
|
|
553
|
+
```tsx fileName="src/routes/{-$locale}/index.tsx"
|
|
554
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
555
|
+
import {
|
|
556
|
+
getRequestHeader,
|
|
557
|
+
getRequestHeaders,
|
|
558
|
+
} from "@tanstack/react-start/server";
|
|
559
|
+
import { getCookie, getIntlayer, getLocale } from "intlayer";
|
|
560
|
+
|
|
561
|
+
export const getLocaleServer = createServerFn().handler(async () => {
|
|
562
|
+
const locale = await getLocale({
|
|
563
|
+
// Get the cookie from the request (default: 'INTLAYER_LOCALE')
|
|
564
|
+
getCookie: (name) => {
|
|
565
|
+
const cookieString = getRequestHeader("cookie");
|
|
566
|
+
|
|
567
|
+
return getCookie(name, cookieString);
|
|
568
|
+
},
|
|
569
|
+
// Get the header from the request (default: 'x-intlayer-locale')
|
|
570
|
+
getHeader: (name) => getRequestHeader(name),
|
|
571
|
+
// Fallback using Accept-Language negotiation
|
|
572
|
+
getAllHeaders: async () => {
|
|
573
|
+
const headers = getRequestHeaders();
|
|
574
|
+
const result: Record<string, string> = {};
|
|
575
|
+
|
|
576
|
+
// Convert the TypedHeaders into a plain Record<string, string>
|
|
577
|
+
for (const [key, value] of headers.entries()) {
|
|
578
|
+
result[key] = value;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
return result;
|
|
582
|
+
},
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
// Retrieve some content using getIntlayer()
|
|
586
|
+
const content = getIntlayer("app", locale);
|
|
587
|
+
|
|
588
|
+
return { locale, content };
|
|
589
|
+
});
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
### Step 14: Configure TypeScript (Optional)
|
|
544
595
|
|
|
545
596
|
Intlayer uses module augmentation to benefit from TypeScript and strengthen your codebase.
|
|
546
597
|
|
|
@@ -561,53 +561,47 @@ Example:
|
|
|
561
561
|
First, install Vue Router:
|
|
562
562
|
|
|
563
563
|
```bash packageManager="npm"
|
|
564
|
-
npm install
|
|
564
|
+
npm install vue-router
|
|
565
565
|
```
|
|
566
566
|
|
|
567
567
|
```bash packageManager="pnpm"
|
|
568
|
-
pnpm add
|
|
568
|
+
pnpm add vue-router
|
|
569
569
|
```
|
|
570
570
|
|
|
571
571
|
```bash packageManager="yarn"
|
|
572
|
-
yarn add
|
|
572
|
+
yarn add vue-router
|
|
573
573
|
```
|
|
574
574
|
|
|
575
575
|
Then, create a router configuration that handles locale-based routing:
|
|
576
576
|
|
|
577
577
|
```js fileName="src/router/index.ts"
|
|
578
578
|
import {
|
|
579
|
-
configuration,
|
|
580
|
-
getPathWithoutLocale,
|
|
581
579
|
localeFlatMap,
|
|
582
|
-
type
|
|
580
|
+
type Locale,
|
|
583
581
|
} from 'intlayer';
|
|
584
582
|
import { createIntlayerClient } from 'vue-intlayer';
|
|
585
583
|
import { createRouter, createWebHistory } from 'vue-router';
|
|
586
584
|
import HomeView from './views/home/HomeView.vue';
|
|
587
585
|
import RootView from './views/root/Root.vue';
|
|
588
586
|
|
|
589
|
-
// Get internationalisation configuration
|
|
590
|
-
const { internationalization, middleware } = configuration;
|
|
591
|
-
const { defaultLocale } = internationalization;
|
|
592
|
-
|
|
593
587
|
/**
|
|
594
588
|
* Declare the routes with locale-specific paths and metadata.
|
|
595
589
|
*/
|
|
596
|
-
const routes = localeFlatMap((
|
|
590
|
+
const routes = localeFlatMap(({ urlPrefix, locale }) => [
|
|
597
591
|
{
|
|
598
|
-
path: `${
|
|
599
|
-
name: `Root-${
|
|
592
|
+
path: `${urlPrefix}/`,
|
|
593
|
+
name: `Root-${locale}`,
|
|
600
594
|
component: RootView,
|
|
601
595
|
meta: {
|
|
602
|
-
locale
|
|
596
|
+
locale,
|
|
603
597
|
},
|
|
604
598
|
},
|
|
605
599
|
{
|
|
606
|
-
path: `${
|
|
607
|
-
name: `Home-${
|
|
600
|
+
path: `${urlPrefix}/home`,
|
|
601
|
+
name: `Home-${locale}`,
|
|
608
602
|
component: HomeView,
|
|
609
603
|
meta: {
|
|
610
|
-
locale
|
|
604
|
+
locale,
|
|
611
605
|
},
|
|
612
606
|
},
|
|
613
607
|
]);
|
|
@@ -622,23 +616,11 @@ export const router = createRouter({
|
|
|
622
616
|
router.beforeEach((to, _from, next) => {
|
|
623
617
|
const client = createIntlayerClient();
|
|
624
618
|
|
|
625
|
-
const metaLocale = to.meta.locale as
|
|
619
|
+
const metaLocale = to.meta.locale as Locale;
|
|
626
620
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
next();
|
|
631
|
-
} else {
|
|
632
|
-
// Fallback: no locale in meta, possibly unmatched route
|
|
633
|
-
// Optional: handle 404 or redirect to default locale
|
|
634
|
-
client.setLocale(defaultLocale);
|
|
635
|
-
|
|
636
|
-
if (middleware.prefixDefault) {
|
|
637
|
-
next(`/${defaultLocale}${getPathWithoutLocale(to.path)}`);
|
|
638
|
-
} else {
|
|
639
|
-
next(getPathWithoutLocale(to.path));
|
|
640
|
-
}
|
|
641
|
-
}
|
|
621
|
+
// Reuse the locale defined in the route meta
|
|
622
|
+
client.setLocale(metaLocale);
|
|
623
|
+
next();
|
|
642
624
|
});
|
|
643
625
|
```
|
|
644
626
|
|
|
@@ -788,7 +770,7 @@ watch(
|
|
|
788
770
|
Tip: For improved SEO and accessibility, use tags such as `<a href="/fr/home" hreflang="fr">` to link to localised pages, as demonstrated in Step 10. This enables search engines to discover and index language-specific URLs correctly. To maintain SPA behaviour, you can prevent the default navigation with @click.prevent, change the locale using useLocale, and programmatically navigate using Vue Router.
|
|
789
771
|
|
|
790
772
|
```html
|
|
791
|
-
<ol
|
|
773
|
+
<ol>
|
|
792
774
|
<li>
|
|
793
775
|
<a
|
|
794
776
|
hreflang="x-default"
|