@intlayer/docs 7.3.15 → 7.4.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.
@@ -19,9 +19,12 @@ slugs:
19
19
  applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
20
20
  youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
21
21
  history:
22
+ - version: 7.4.0
23
+ date: 2025-12-11
24
+ changes: أضف validatePrefix وشرح خطوة 14: معالجة صفحات 404 مع الطرق المعتمدة على اللغة.
22
25
  - version: 7.3.9
23
26
  date: 2025-12-05
24
- changes: Add step 13: Retrieve the locale in your server actions (Optional)
27
+ changes: أضف خطوة 13: كيفية جلب اللغة الحالية داخل عمليات الخادم (اختياري)
25
28
  - version: 5.8.1
26
29
  date: 2025-09-09
27
30
  changes: أضيف لـ Tanstack Start
@@ -599,7 +602,134 @@ export const getLocaleServer = createServerFn().handler(async () => {
599
602
 
600
603
  ---
601
604
 
602
- ### الخطوة 14: تكوين TypeScript (اختياري)
605
+ ### الخطوة 14: إدارة الصفحات غير الموجودة (اختياري)
606
+
607
+ عندما يزور المستخدم صفحة غير موجودة، يمكنك عرض صفحة مخصصة "غير موجودة" وقد يؤثر بادئة اللغة على طريقة تشغيل صفحة "غير موجودة".
608
+
609
+ #### فهم معالجة 404 في TanStack Router مع بادئات اللغة
610
+
611
+ في TanStack Router، يتطلب التعامل مع صفحات 404 باستخدام المسارات المترجمة نهجًا متعدد الطبقات:
612
+
613
+ 1. **مسار 404 مخصص**: مسار محدد لعرض واجهة المستخدم 404
614
+ 2. **التحقق على مستوى المسار**: يتحقق من بادئات اللغة ويعيد توجيه غير الصالحة إلى 404
615
+ 3. **مسار catch-all**: يلتقط أي مسارات غير متطابقة داخل مقطع اللغة
616
+
617
+ ```tsx fileName="src/routes/{-$locale}/404.tsx"
618
+ import { createFileRoute } from "@tanstack/react-router";
619
+
620
+ // هذا ينشئ مسارًا مخصصًا /[locale]/404
621
+ // يتم استخدامه كمسار مباشر واستيراده كعنصر في ملفات أخرى
622
+ export const Route = createFileRoute("/{-$locale}/404")({
623
+ component: NotFoundComponent,
624
+ });
625
+
626
+ // يتم تصديره بشكل منفصل حتى يمكن إعادة استخدامه في notFoundComponent والمسارات catch-all
627
+ export function NotFoundComponent() {
628
+ return (
629
+ <div>
630
+ <h1>404</h1>
631
+ </div>
632
+ );
633
+ }
634
+ ```
635
+
636
+ ```tsx fileName="src/routes/__root.tsx"
637
+ import { createRootRoute } from "@tanstack/react-router";
638
+
639
+ // المسار الجذري يعمل كتخطيط على المستوى الأعلى
640
+ // لا يتعامل مع 404 مباشرة - يتم تفويض ذلك إلى المسارات الفرعية
641
+ // هذا يحافظ على الجذر بسيطًا ويتيح للمسارات الواعية باللغة إدارة منطق 404 الخاص بها
642
+ export const Route = createRootRoute({
643
+ component: Outlet,
644
+ });
645
+ ```
646
+
647
+ ```tsx fileName="src/routes/{-$locale}/route.tsx"
648
+ import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
649
+ import { validatePrefix } from "intlayer";
650
+ import { IntlayerProvider, useLocale } from "react-intlayer";
651
+
652
+ import { LocaleSwitcher } from "@/components/locale-switcher";
653
+ import { NotFoundComponent } from "./404";
654
+
655
+ export const Route = createFileRoute("/{-$locale}")({
656
+ // beforeLoad يعمل قبل عرض المسار (على كل من الخادم والعميل)
657
+ // إنه المكان المثالي للتحقق من بادئة اللغة
658
+ beforeLoad: ({ params }) => {
659
+ // الحصول على اللغة من معاملات المسار (وليس من رؤوس الخادم، حيث يعمل beforeLoad على كل من العميل والخادم)
660
+ const localeParam = params.locale;
661
+
662
+ // validatePrefix يتحقق مما إذا كانت اللغة صالحة وفقًا لتكوين intlayer الخاص بك
663
+ // إرجاع: { isValid: boolean, localePrefix: string }
664
+ // - isValid: true إذا كانت البادئة تطابق لغة مُكوَّنة (أو فارغة عندما تكون البادئة اختيارية)
665
+ // - localePrefix: البادئة المُتحقق منها أو بادئة اللغة الافتراضية لإعادة التوجيه
666
+ const { isValid, localePrefix } = validatePrefix(localeParam);
667
+
668
+ if (isValid) {
669
+ // اللغة صالحة، السماح للمسار بالعرض بشكل طبيعي
670
+ return;
671
+ }
672
+
673
+ // بادئة لغة غير صالحة (على سبيل المثال، /xyz/about حيث "xyz" ليست لغة صالحة)
674
+ // إعادة التوجيه إلى صفحة 404 ببادئة لغة صالحة
675
+ // يضمن هذا أن صفحة 404 لا تزال محلية بشكل صحيح
676
+ throw redirect({
677
+ to: "/{-$locale}/404",
678
+ params: { locale: localePrefix },
679
+ });
680
+ },
681
+ component: RouteComponent,
682
+ // يتم استدعاء notFoundComponent عندما لا يوجد مسار فرعي
683
+ // على سبيل المثال، /en/صفحة-غير-موجودة يطلق هذا داخل تخطيط /en
684
+ notFoundComponent: NotFoundLayout,
685
+ });
686
+
687
+ function RouteComponent() {
688
+ const { defaultLocale } = useLocale();
689
+ const { locale } = Route.useParams();
690
+
691
+ return (
692
+ // لف كامل مقطع اللغة بـ IntlayerProvider
693
+ // يعود إلى defaultLocale عندما تكون معلمة اللغة undefined (وضع البادئة الاختياري)
694
+ <IntlayerProvider locale={locale ?? defaultLocale}>
695
+ <Outlet />
696
+ </IntlayerProvider>
697
+ );
698
+ }
699
+
700
+ // NotFoundLayout يلف عنصر 404 بـ IntlayerProvider
701
+ // يضمن هذا أن الترجمات لا تزال تعمل على صفحة 404
702
+ function NotFoundLayout() {
703
+ const { defaultLocale } = useLocale();
704
+ const { locale } = Route.useParams();
705
+
706
+ return (
707
+ <IntlayerProvider locale={locale ?? defaultLocale}>
708
+ <NotFoundComponent />
709
+ {/* تضمين LocaleSwitcher حتى يتمكن المستخدمون من تغيير اللغة حتى على 404 */}
710
+ <LocaleSwitcher />
711
+ </IntlayerProvider>
712
+ );
713
+ }
714
+ ```
715
+
716
+ ```tsx fileName="src/routes/{-$locale}/$.tsx"
717
+ import { createFileRoute } from "@tanstack/react-router";
718
+
719
+ import { NotFoundComponent } from "./404";
720
+
721
+ // المسار $ (splat/catch-all) يطابق أي مسار لا يطابق المسارات الأخرى
722
+ // على سبيل المثال، /en/بعض/المسار/المتداخل/بعمق/غير-صالح
723
+ // يضمن هذا أن جميع المسارات غير المتطابقة داخل اللغة تعرض صفحة 404
724
+ // بدون هذا، قد تعرض المسارات العميقة غير المتطابقة صفحة فارغة أو خطأ
725
+ export const Route = createFileRoute("/{-$locale}/$")({
726
+ component: NotFoundComponent,
727
+ });
728
+ ```
729
+
730
+ ---
731
+
732
+ ### الخطوة 15: تكوين TypeScript (اختياري)
603
733
 
604
734
  يستخدم Intlayer توسيع الوحدات (module augmentation) للاستفادة من TypeScript وجعل قاعدة الشيفرة الخاصة بك أقوى.
605
735
 
@@ -19,9 +19,12 @@ slugs:
19
19
  applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
20
20
  youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
21
21
  history:
22
+ - version: 7.4.0
23
+ date: 2025-12-11
24
+ changes: Füge validatePrefix hinzu und ergänze Schritt 14: 404-Seiten mit lokalisierten Routen behandeln.
22
25
  - version: 7.3.9
23
26
  date: 2025-12-05
24
- changes: Add step 13: Retrieve the locale in your server actions (Optional)
27
+ changes: Füge Schritt 13 hinzu: Zugriff auf die aktuelle Locale in Serveraktionen (Optional)
25
28
  - version: 5.8.1
26
29
  date: 2025-09-09
27
30
  changes: Hinzugefügt für Tanstack Start
@@ -614,7 +617,134 @@ export const getLocaleServer = createServerFn().handler(async () => {
614
617
 
615
618
  ---
616
619
 
617
- ### Schritt 14: TypeScript konfigurieren (optional)
620
+ ### Schritt 14: Nicht gefundene Seiten verwalten (optional)
621
+
622
+ Wenn ein Benutzer eine nicht existierende Seite besucht, können Sie eine benutzerdefinierte Seite "Nicht gefunden" anzeigen, und das Locale-Präfix kann beeinflussen, wie die Seite "Nicht gefunden" ausgelöst wird.
623
+
624
+ #### Verstehen der 404-Behandlung von TanStack Router mit Locale-Präfixen
625
+
626
+ In TanStack Router erfordert die Behandlung von 404-Seiten mit lokalisierten Routen einen mehrschichtigen Ansatz:
627
+
628
+ 1. **Dedizierte 404-Route**: Eine spezifische Route zur Anzeige der 404-Benutzeroberfläche
629
+ 2. **Validierung auf Routenebene**: Validiert Locale-Präfixe und leitet ungültige zu 404 weiter
630
+ 3. **Catch-all-Route**: Erfasst alle nicht übereinstimmenden Pfade innerhalb des Locale-Segments
631
+
632
+ ```tsx fileName="src/routes/{-$locale}/404.tsx"
633
+ import { createFileRoute } from "@tanstack/react-router";
634
+
635
+ // Dies erstellt eine dedizierte /[locale]/404 Route
636
+ // Sie wird sowohl als direkte Route verwendet als auch als Komponente in anderen Dateien importiert
637
+ export const Route = createFileRoute("/{-$locale}/404")({
638
+ component: NotFoundComponent,
639
+ });
640
+
641
+ // Separately exportiert, damit es in notFoundComponent und catch-all Routen wiederverwendet werden kann
642
+ export function NotFoundComponent() {
643
+ return (
644
+ <div>
645
+ <h1>404</h1>
646
+ </div>
647
+ );
648
+ }
649
+ ```
650
+
651
+ ```tsx fileName="src/routes/__root.tsx"
652
+ import { createRootRoute } from "@tanstack/react-router";
653
+
654
+ // Die Root-Route dient als Layout auf oberster Ebene
655
+ // Sie behandelt 404s nicht direkt - das wird an untergeordnete Routen delegiert
656
+ // Dies hält die Root einfach und ermöglicht es locale-bewussten Routen, ihre eigene 404-Logik zu verwalten
657
+ export const Route = createRootRoute({
658
+ component: Outlet,
659
+ });
660
+ ```
661
+
662
+ ```tsx fileName="src/routes/{-$locale}/route.tsx"
663
+ import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
664
+ import { validatePrefix } from "intlayer";
665
+ import { IntlayerProvider, useLocale } from "react-intlayer";
666
+
667
+ import { LocaleSwitcher } from "@/components/locale-switcher";
668
+ import { NotFoundComponent } from "./404";
669
+
670
+ export const Route = createFileRoute("/{-$locale}")({
671
+ // beforeLoad läuft, bevor die Route gerendert wird (sowohl auf Server als auch Client)
672
+ // Es ist der ideale Ort, um das Locale-Präfix zu validieren
673
+ beforeLoad: ({ params }) => {
674
+ // Locale aus Routenparametern abrufen (nicht aus Server-Headern, da beforeLoad sowohl auf Client als auch Server läuft)
675
+ const localeParam = params.locale;
676
+
677
+ // validatePrefix prüft, ob die Locale gemäß Ihrer intlayer-Konfiguration gültig ist
678
+ // Gibt zurück: { isValid: boolean, localePrefix: string }
679
+ // - isValid: true, wenn das Präfix mit einer konfigurierten Locale übereinstimmt (oder leer ist, wenn das Präfix optional ist)
680
+ // - localePrefix: das validierte Präfix oder das Standard-Locale-Präfix für Umleitungen
681
+ const { isValid, localePrefix } = validatePrefix(localeParam);
682
+
683
+ if (isValid) {
684
+ // Locale ist gültig, Route normal rendern lassen
685
+ return;
686
+ }
687
+
688
+ // Ungültiges Locale-Präfix (z. B. /xyz/about, wobei "xyz" keine gültige Locale ist)
689
+ // Zur 404-Seite mit einem gültigen Locale-Präfix umleiten
690
+ // Dies stellt sicher, dass die 404-Seite weiterhin korrekt lokalisiert ist
691
+ throw redirect({
692
+ to: "/{-$locale}/404",
693
+ params: { locale: localePrefix },
694
+ });
695
+ },
696
+ component: RouteComponent,
697
+ // notFoundComponent wird aufgerufen, wenn eine untergeordnete Route nicht existiert
698
+ // z. B. löst /en/nicht-vorhandene-seite dies innerhalb des /en-Layouts aus
699
+ notFoundComponent: NotFoundLayout,
700
+ });
701
+
702
+ function RouteComponent() {
703
+ const { defaultLocale } = useLocale();
704
+ const { locale } = Route.useParams();
705
+
706
+ return (
707
+ // Den gesamten Locale-Segment mit IntlayerProvider umschließen
708
+ // Fällt auf defaultLocale zurück, wenn der locale-Parameter undefined ist (optionaler Präfix-Modus)
709
+ <IntlayerProvider locale={locale ?? defaultLocale}>
710
+ <Outlet />
711
+ </IntlayerProvider>
712
+ );
713
+ }
714
+
715
+ // NotFoundLayout umschließt die 404-Komponente mit IntlayerProvider
716
+ // Dies stellt sicher, dass Übersetzungen auf der 404-Seite weiterhin funktionieren
717
+ function NotFoundLayout() {
718
+ const { defaultLocale } = useLocale();
719
+ const { locale } = Route.useParams();
720
+
721
+ return (
722
+ <IntlayerProvider locale={locale ?? defaultLocale}>
723
+ <NotFoundComponent />
724
+ {/* LocaleSwitcher einbinden, damit Benutzer die Sprache auch auf 404 ändern können */}
725
+ <LocaleSwitcher />
726
+ </IntlayerProvider>
727
+ );
728
+ }
729
+ ```
730
+
731
+ ```tsx fileName="src/routes/{-$locale}/$.tsx"
732
+ import { createFileRoute } from "@tanstack/react-router";
733
+
734
+ import { NotFoundComponent } from "./404";
735
+
736
+ // Die $ (splat/catch-all) Route passt auf jeden Pfad, der nicht mit anderen Routen übereinstimmt
737
+ // z. B. /en/irgendein/tief/verschachtelter/ungültiger/pfad
738
+ // Dies stellt sicher, dass ALLE nicht übereinstimmenden Pfade innerhalb einer Locale die 404-Seite anzeigen
739
+ // Ohne dies könnten nicht übereinstimmende tiefe Pfade eine leere Seite oder einen Fehler anzeigen
740
+ export const Route = createFileRoute("/{-$locale}/$")({
741
+ component: NotFoundComponent,
742
+ });
743
+ ```
744
+
745
+ ---
746
+
747
+ ### Schritt 15: TypeScript konfigurieren (optional)
618
748
 
619
749
  Intlayer verwendet Module Augmentation, um die Vorteile von TypeScript zu nutzen und Ihren Code robuster zu machen.
620
750
 
@@ -19,6 +19,9 @@ slugs:
19
19
  applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
20
20
  youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
21
21
  history:
22
+ - version: 7.4.0
23
+ date: 2025-12-11
24
+ changes: Introduce validatePrefix and add step 14: Handling 404 pages with localized routes.
22
25
  - version: 7.3.9
23
26
  date: 2025-12-05
24
27
  changes: Add step 13: Retrieve the locale in your server actions (Optional)
@@ -611,7 +614,134 @@ export const getLocaleServer = createServerFn().handler(async () => {
611
614
 
612
615
  ---
613
616
 
614
- ### Step 14: Configure TypeScript (Optional)
617
+ ### Step 14: Manage not found pages (Optional)
618
+
619
+ When a user visits a non-existing page, you can display a custom not found page and the locale prefix may impact the way the not found page is triggered.
620
+
621
+ #### Understanding TanStack Router's 404 Handling with Locale Prefixes
622
+
623
+ In TanStack Router, handling 404 pages with localized routes requires a multi-layered approach:
624
+
625
+ 1. **Dedicated 404 route**: A specific route to display the 404 UI
626
+ 2. **Route-level validation**: Validates locale prefixes and redirects invalid ones to 404
627
+ 3. **Catch-all route**: Captures any unmatched paths within the locale segment
628
+
629
+ ```tsx fileName="src/routes/{-$locale}/404.tsx"
630
+ import { createFileRoute } from "@tanstack/react-router";
631
+
632
+ // This creates a dedicated /[locale]/404 route
633
+ // It's used both as a direct route and imported as a component in other files
634
+ export const Route = createFileRoute("/{-$locale}/404")({
635
+ component: NotFoundComponent,
636
+ });
637
+
638
+ // Exported separately so it can be reused in notFoundComponent and catch-all routes
639
+ export function NotFoundComponent() {
640
+ return (
641
+ <div>
642
+ <h1>404</h1>
643
+ </div>
644
+ );
645
+ }
646
+ ```
647
+
648
+ ```tsx fileName="src/routes/__root.tsx"
649
+ import { createRootRoute } from "@tanstack/react-router";
650
+
651
+ // The root route serves as the top-level layout
652
+ // It doesn't handle 404s directly - that's delegated to child routes
653
+ // This keeps the root simple and lets locale-aware routes manage their own 404 logic
654
+ export const Route = createRootRoute({
655
+ component: Outlet,
656
+ });
657
+ ```
658
+
659
+ ```tsx fileName="src/routes/{-$locale}/route.tsx"
660
+ import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
661
+ import { validatePrefix } from "intlayer";
662
+ import { IntlayerProvider, useLocale } from "react-intlayer";
663
+
664
+ import { LocaleSwitcher } from "@/components/locale-switcher";
665
+ import { NotFoundComponent } from "./404";
666
+
667
+ export const Route = createFileRoute("/{-$locale}")({
668
+ // beforeLoad runs before the route renders (on both server and client)
669
+ // It's the ideal place to validate the locale prefix
670
+ beforeLoad: ({ params }) => {
671
+ // Get locale from route params (not from server headers, as beforeLoad runs on both client and server)
672
+ const localeParam = params.locale;
673
+
674
+ // validatePrefix checks if the locale is valid according to your intlayer config
675
+ // Returns: { isValid: boolean, localePrefix: string }
676
+ // - isValid: true if the prefix matches a configured locale (or is empty when prefix is optional)
677
+ // - localePrefix: the validated prefix or the default locale prefix for redirects
678
+ const { isValid, localePrefix } = validatePrefix(localeParam);
679
+
680
+ if (isValid) {
681
+ // Locale is valid, allow the route to render normally
682
+ return;
683
+ }
684
+
685
+ // Invalid locale prefix (e.g., /xyz/about where "xyz" isn't a valid locale)
686
+ // Redirect to the 404 page with a valid locale prefix
687
+ // This ensures the 404 page is still properly localized
688
+ throw redirect({
689
+ to: "/{-$locale}/404",
690
+ params: { locale: localePrefix },
691
+ });
692
+ },
693
+ component: RouteComponent,
694
+ // notFoundComponent is called when a child route doesn't exist
695
+ // e.g., /en/non-existent-page triggers this within the /en layout
696
+ notFoundComponent: NotFoundLayout,
697
+ });
698
+
699
+ function RouteComponent() {
700
+ const { defaultLocale } = useLocale();
701
+ const { locale } = Route.useParams();
702
+
703
+ return (
704
+ // Wrap the entire locale segment with IntlayerProvider
705
+ // Falls back to defaultLocale when locale param is undefined (optional prefix mode)
706
+ <IntlayerProvider locale={locale ?? defaultLocale}>
707
+ <Outlet />
708
+ </IntlayerProvider>
709
+ );
710
+ }
711
+
712
+ // NotFoundLayout wraps the 404 component with IntlayerProvider
713
+ // This ensures translations still work on the 404 page
714
+ function NotFoundLayout() {
715
+ const { defaultLocale } = useLocale();
716
+ const { locale } = Route.useParams();
717
+
718
+ return (
719
+ <IntlayerProvider locale={locale ?? defaultLocale}>
720
+ <NotFoundComponent />
721
+ {/* Include LocaleSwitcher so users can change language even on 404 */}
722
+ <LocaleSwitcher />
723
+ </IntlayerProvider>
724
+ );
725
+ }
726
+ ```
727
+
728
+ ```tsx fileName="src/routes/{-$locale}/$.tsx"
729
+ import { createFileRoute } from "@tanstack/react-router";
730
+
731
+ import { NotFoundComponent } from "./404";
732
+
733
+ // The $ (splat/catch-all) route matches any path that doesn't match other routes
734
+ // e.g., /en/some/deeply/nested/invalid/path
735
+ // This ensures ALL unmatched paths within a locale show the 404 page
736
+ // Without this, unmatched deep paths might show a blank page or error
737
+ export const Route = createFileRoute("/{-$locale}/$")({
738
+ component: NotFoundComponent,
739
+ });
740
+ ```
741
+
742
+ ---
743
+
744
+ ### Step 15: Configure TypeScript (Optional)
615
745
 
616
746
  Intlayer uses module augmentation to get benefits of TypeScript and make your codebase stronger.
617
747
 
@@ -19,6 +19,9 @@ slugs:
19
19
  applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
20
20
  youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
21
21
  history:
22
+ - version: 7.4.0
23
+ date: 2025-12-11
24
+ changes: Introduce validatePrefix and add step 14: Handling 404 pages with localized routes.
22
25
  - version: 7.3.9
23
26
  date: 2025-12-05
24
27
  changes: Add step 13: Retrieve the locale in your server actions (Optional)
@@ -602,7 +605,134 @@ export const getLocaleServer = createServerFn().handler(async () => {
602
605
 
603
606
  ---
604
607
 
605
- ### Step 14: Configure TypeScript (Optional)
608
+ ### Step 14: Manage not found pages (Optional)
609
+
610
+ When a user visits a non-existing page, you can display a custom not found page and the locale prefix may impact the way the not found page is triggered.
611
+
612
+ #### Understanding TanStack Router's 404 Handling with Locale Prefixes
613
+
614
+ In TanStack Router, handling 404 pages with localized routes requires a multi-layered approach:
615
+
616
+ 1. **Dedicated 404 route**: A specific route to display the 404 UI
617
+ 2. **Route-level validation**: Validates locale prefixes and redirects invalid ones to 404
618
+ 3. **Catch-all route**: Captures any unmatched paths within the locale segment
619
+
620
+ ```tsx fileName="src/routes/{-$locale}/404.tsx"
621
+ import { createFileRoute } from "@tanstack/react-router";
622
+
623
+ // This creates a dedicated /[locale]/404 route
624
+ // It's used both as a direct route and imported as a component in other files
625
+ export const Route = createFileRoute("/{-$locale}/404")({
626
+ component: NotFoundComponent,
627
+ });
628
+
629
+ // Exported separately so it can be reused in notFoundComponent and catch-all routes
630
+ export function NotFoundComponent() {
631
+ return (
632
+ <div>
633
+ <h1>404</h1>
634
+ </div>
635
+ );
636
+ }
637
+ ```
638
+
639
+ ```tsx fileName="src/routes/__root.tsx"
640
+ import { createRootRoute } from "@tanstack/react-router";
641
+
642
+ // The root route serves as the top-level layout
643
+ // It doesn't handle 404s directly - that's delegated to child routes
644
+ // This keeps the root simple and lets locale-aware routes manage their own 404 logic
645
+ export const Route = createRootRoute({
646
+ component: Outlet,
647
+ });
648
+ ```
649
+
650
+ ```tsx fileName="src/routes/{-$locale}/route.tsx"
651
+ import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
652
+ import { validatePrefix } from "intlayer";
653
+ import { IntlayerProvider, useLocale } from "react-intlayer";
654
+
655
+ import { LocaleSwitcher } from "@/components/locale-switcher";
656
+ import { NotFoundComponent } from "./404";
657
+
658
+ export const Route = createFileRoute("/{-$locale}")({
659
+ // beforeLoad runs before the route renders (on both server and client)
660
+ // It's the ideal place to validate the locale prefix
661
+ beforeLoad: ({ params }) => {
662
+ // Get locale from route params (not from server headers, as beforeLoad runs on both client and server)
663
+ const localeParam = params.locale;
664
+
665
+ // validatePrefix checks if the locale is valid according to your intlayer config
666
+ // Returns: { isValid: boolean, localePrefix: string }
667
+ // - isValid: true if the prefix matches a configured locale (or is empty when prefix is optional)
668
+ // - localePrefix: the validated prefix or the default locale prefix for redirects
669
+ const { isValid, localePrefix } = validatePrefix(localeParam);
670
+
671
+ if (isValid) {
672
+ // Locale is valid, allow the route to render normally
673
+ return;
674
+ }
675
+
676
+ // Invalid locale prefix (e.g., /xyz/about where "xyz" isn't a valid locale)
677
+ // Redirect to the 404 page with a valid locale prefix
678
+ // This ensures the 404 page is still properly localized
679
+ throw redirect({
680
+ to: "/{-$locale}/404",
681
+ params: { locale: localePrefix },
682
+ });
683
+ },
684
+ component: RouteComponent,
685
+ // notFoundComponent is called when a child route doesn't exist
686
+ // e.g., /en/non-existent-page triggers this within the /en layout
687
+ notFoundComponent: NotFoundLayout,
688
+ });
689
+
690
+ function RouteComponent() {
691
+ const { defaultLocale } = useLocale();
692
+ const { locale } = Route.useParams();
693
+
694
+ return (
695
+ // Wrap the entire locale segment with IntlayerProvider
696
+ // Falls back to defaultLocale when locale param is undefined (optional prefix mode)
697
+ <IntlayerProvider locale={locale ?? defaultLocale}>
698
+ <Outlet />
699
+ </IntlayerProvider>
700
+ );
701
+ }
702
+
703
+ // NotFoundLayout wraps the 404 component with IntlayerProvider
704
+ // This ensures translations still work on the 404 page
705
+ function NotFoundLayout() {
706
+ const { defaultLocale } = useLocale();
707
+ const { locale } = Route.useParams();
708
+
709
+ return (
710
+ <IntlayerProvider locale={locale ?? defaultLocale}>
711
+ <NotFoundComponent />
712
+ {/* Include LocaleSwitcher so users can change language even on 404 */}
713
+ <LocaleSwitcher />
714
+ </IntlayerProvider>
715
+ );
716
+ }
717
+ ```
718
+
719
+ ```tsx fileName="src/routes/{-$locale}/$.tsx"
720
+ import { createFileRoute } from "@tanstack/react-router";
721
+
722
+ import { NotFoundComponent } from "./404";
723
+
724
+ // The $ (splat/catch-all) route matches any path that doesn't match other routes
725
+ // e.g., /en/some/deeply/nested/invalid/path
726
+ // This ensures ALL unmatched paths within a locale show the 404 page
727
+ // Without this, unmatched deep paths might show a blank page or error
728
+ export const Route = createFileRoute("/{-$locale}/$")({
729
+ component: NotFoundComponent,
730
+ });
731
+ ```
732
+
733
+ ---
734
+
735
+ ### Step 15: Configure TypeScript (Optional)
606
736
 
607
737
  Intlayer uses module augmentation to benefit from TypeScript and strengthen your codebase.
608
738