@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: Introduz validatePrefix e adiciona o passo 14: Tratamento de páginas 404 com rotas localizadas.
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: Adiciona o passo 13: Recuperar o locale em suas server actions (Opcional)
25
28
  - version: 5.8.1
26
29
  date: 2025-09-09
27
30
  changes: Adicionado para Tanstack Start
@@ -612,7 +615,134 @@ export const getLocaleServer = createServerFn().handler(async () => {
612
615
 
613
616
  ---
614
617
 
615
- ### Passo 14: Configurar o TypeScript (Opcional)
618
+ ### Passo 14: Gerenciar páginas não encontradas (Opcional)
619
+
620
+ Quando um usuário visita uma página inexistente, você pode exibir uma página personalizada de não encontrada e o prefixo de locale pode afetar a forma como a página de não encontrada é acionada.
621
+
622
+ #### Entendendo o tratamento de 404 do TanStack Router com prefixos de locale
623
+
624
+ No TanStack Router, lidar com páginas 404 com rotas localizadas requer uma abordagem multicamadas:
625
+
626
+ 1. **Rota 404 dedicada**: Uma rota específica para exibir a interface 404
627
+ 2. **Validação no nível da rota**: Valida os prefixos de locale e redireciona os inválidos para 404
628
+ 3. **Rota catch-all**: Captura todos os caminhos não correspondentes dentro do segmento de locale
629
+
630
+ ```tsx fileName="src/routes/{-$locale}/404.tsx"
631
+ import { createFileRoute } from "@tanstack/react-router";
632
+
633
+ // Isso cria uma rota dedicada /[locale]/404
634
+ // É usada tanto como uma rota direta quanto importada como um componente em outros arquivos
635
+ export const Route = createFileRoute("/{-$locale}/404")({
636
+ component: NotFoundComponent,
637
+ });
638
+
639
+ // Exportado separadamente para que possa ser reutilizado em notFoundComponent e rotas catch-all
640
+ export function NotFoundComponent() {
641
+ return (
642
+ <div>
643
+ <h1>404</h1>
644
+ </div>
645
+ );
646
+ }
647
+ ```
648
+
649
+ ```tsx fileName="src/routes/__root.tsx"
650
+ import { createRootRoute } from "@tanstack/react-router";
651
+
652
+ // A rota raiz serve como o layout de nível superior
653
+ // Ela não trata 404s diretamente - isso é delegado às rotas filhas
654
+ // Isso mantém a raiz simples e permite que rotas conscientes de locale gerenciem sua própria lógica 404
655
+ export const Route = createRootRoute({
656
+ component: Outlet,
657
+ });
658
+ ```
659
+
660
+ ```tsx fileName="src/routes/{-$locale}/route.tsx"
661
+ import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
662
+ import { validatePrefix } from "intlayer";
663
+ import { IntlayerProvider, useLocale } from "react-intlayer";
664
+
665
+ import { LocaleSwitcher } from "@/components/locale-switcher";
666
+ import { NotFoundComponent } from "./404";
667
+
668
+ export const Route = createFileRoute("/{-$locale}")({
669
+ // beforeLoad executa antes da rota ser renderizada (tanto no servidor quanto no cliente)
670
+ // É o lugar ideal para validar o prefixo de locale
671
+ beforeLoad: ({ params }) => {
672
+ // Obter locale dos parâmetros da rota (não dos cabeçalhos do servidor, pois beforeLoad executa tanto no cliente quanto no servidor)
673
+ const localeParam = params.locale;
674
+
675
+ // validatePrefix verifica se o locale é válido de acordo com sua configuração intlayer
676
+ // Retorna: { isValid: boolean, localePrefix: string }
677
+ // - isValid: true se o prefixo corresponder a um locale configurado (ou estiver vazio quando o prefixo for opcional)
678
+ // - localePrefix: o prefixo validado ou o prefixo de locale padrão para redirecionamentos
679
+ const { isValid, localePrefix } = validatePrefix(localeParam);
680
+
681
+ if (isValid) {
682
+ // Locale é válido, permitir que a rota seja renderizada normalmente
683
+ return;
684
+ }
685
+
686
+ // Prefixo de locale inválido (por exemplo, /xyz/about onde "xyz" não é um locale válido)
687
+ // Redirecionar para a página 404 com um prefixo de locale válido
688
+ // Isso garante que a página 404 ainda esteja adequadamente localizada
689
+ throw redirect({
690
+ to: "/{-$locale}/404",
691
+ params: { locale: localePrefix },
692
+ });
693
+ },
694
+ component: RouteComponent,
695
+ // notFoundComponent é chamado quando uma rota filha não existe
696
+ // por exemplo, /en/pagina-inexistente dispara isso dentro do layout /en
697
+ notFoundComponent: NotFoundLayout,
698
+ });
699
+
700
+ function RouteComponent() {
701
+ const { defaultLocale } = useLocale();
702
+ const { locale } = Route.useParams();
703
+
704
+ return (
705
+ // Envolver todo o segmento de locale com IntlayerProvider
706
+ // Volta para defaultLocale quando o parâmetro locale é undefined (modo de prefixo opcional)
707
+ <IntlayerProvider locale={locale ?? defaultLocale}>
708
+ <Outlet />
709
+ </IntlayerProvider>
710
+ );
711
+ }
712
+
713
+ // NotFoundLayout envolve o componente 404 com IntlayerProvider
714
+ // Isso garante que as traduções ainda funcionem na página 404
715
+ function NotFoundLayout() {
716
+ const { defaultLocale } = useLocale();
717
+ const { locale } = Route.useParams();
718
+
719
+ return (
720
+ <IntlayerProvider locale={locale ?? defaultLocale}>
721
+ <NotFoundComponent />
722
+ {/* Incluir LocaleSwitcher para que os usuários possam alterar o idioma mesmo em 404 */}
723
+ <LocaleSwitcher />
724
+ </IntlayerProvider>
725
+ );
726
+ }
727
+ ```
728
+
729
+ ```tsx fileName="src/routes/{-$locale}/$.tsx"
730
+ import { createFileRoute } from "@tanstack/react-router";
731
+
732
+ import { NotFoundComponent } from "./404";
733
+
734
+ // A rota $ (splat/catch-all) corresponde a qualquer caminho que não corresponda a outras rotas
735
+ // por exemplo, /en/algum/caminho/profundamente/aninhado/invalido
736
+ // Isso garante que TODOS os caminhos não correspondentes dentro de um locale mostrem a página 404
737
+ // Sem isso, caminhos profundos não correspondentes podem mostrar uma página em branco ou erro
738
+ export const Route = createFileRoute("/{-$locale}/$")({
739
+ component: NotFoundComponent,
740
+ });
741
+ ```
742
+
743
+ ---
744
+
745
+ ### Passo 15: Configurar o TypeScript (Opcional)
616
746
 
617
747
  O Intlayer utiliza a ampliação de módulos para aproveitar os benefícios do TypeScript e fortalecer sua base de código.
618
748
 
@@ -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: Получение текущей локали в ваших server actions (опционально)
25
28
  - version: 5.8.1
26
29
  date: 2025-09-09
27
30
  changes: Добавлено для Tanstack Start
@@ -602,7 +605,134 @@ export const getLocaleServer = createServerFn().handler(async () => {
602
605
 
603
606
  ---
604
607
 
605
- ### Шаг 14: Настройка TypeScript (необязательно)
608
+ ### Шаг 14: Управление страницами "не найдено" (необязательно)
609
+
610
+ Когда пользователь посещает несуществующую страницу, вы можете отобразить пользовательскую страницу "не найдено", и префикс локали может повлиять на способ срабатывания страницы "не найдено".
611
+
612
+ #### Понимание обработки 404 в TanStack Router с префиксами локали
613
+
614
+ В TanStack Router обработка страниц 404 с локализованными маршрутами требует многоуровневого подхода:
615
+
616
+ 1. **Выделенный маршрут 404**: Специфический маршрут для отображения интерфейса 404
617
+ 2. **Проверка на уровне маршрута**: Проверяет префиксы локали и перенаправляет недействительные на 404
618
+ 3. **Маршрут catch-all**: Перехватывает все несовпадающие пути в сегменте локали
619
+
620
+ ```tsx fileName="src/routes/{-$locale}/404.tsx"
621
+ import { createFileRoute } from "@tanstack/react-router";
622
+
623
+ // Это создает выделенный маршрут /[locale]/404
624
+ // Он используется как прямой маршрут и импортируется как компонент в других файлах
625
+ export const Route = createFileRoute("/{-$locale}/404")({
626
+ component: NotFoundComponent,
627
+ });
628
+
629
+ // Экспортируется отдельно, чтобы можно было повторно использовать в notFoundComponent и catch-all маршрутах
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
+ // Корневой маршрут служит макетом верхнего уровня
643
+ // Он не обрабатывает 404 напрямую - это делегировано дочерним маршрутам
644
+ // Это сохраняет корень простым и позволяет маршрутам, осведомленным о локали, управлять своей собственной логикой 404
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 выполняется до рендеринга маршрута (как на сервере, так и на клиенте)
660
+ // Это идеальное место для проверки префикса локали
661
+ beforeLoad: ({ params }) => {
662
+ // Получить локаль из параметров маршрута (не из заголовков сервера, так как beforeLoad выполняется как на клиенте, так и на сервере)
663
+ const localeParam = params.locale;
664
+
665
+ // validatePrefix проверяет, является ли локаль действительной согласно вашей конфигурации intlayer
666
+ // Возвращает: { isValid: boolean, localePrefix: string }
667
+ // - isValid: true, если префикс соответствует настроенной локали (или пуст, когда префикс опционален)
668
+ // - localePrefix: проверенный префикс или префикс локали по умолчанию для редиректов
669
+ const { isValid, localePrefix } = validatePrefix(localeParam);
670
+
671
+ if (isValid) {
672
+ // Локаль действительна, разрешить маршруту рендериться нормально
673
+ return;
674
+ }
675
+
676
+ // Недействительный префикс локали (например, /xyz/about, где "xyz" не является действительной локалью)
677
+ // Перенаправить на страницу 404 с действительным префиксом локали
678
+ // Это гарантирует, что страница 404 все еще правильно локализована
679
+ throw redirect({
680
+ to: "/{-$locale}/404",
681
+ params: { locale: localePrefix },
682
+ });
683
+ },
684
+ component: RouteComponent,
685
+ // notFoundComponent вызывается, когда дочерний маршрут не существует
686
+ // например, /en/несуществующая-страница запускает это в макете /en
687
+ notFoundComponent: NotFoundLayout,
688
+ });
689
+
690
+ function RouteComponent() {
691
+ const { defaultLocale } = useLocale();
692
+ const { locale } = Route.useParams();
693
+
694
+ return (
695
+ // Обернуть весь сегмент локали в IntlayerProvider
696
+ // Возвращается к defaultLocale, когда параметр locale равен undefined (режим опционального префикса)
697
+ <IntlayerProvider locale={locale ?? defaultLocale}>
698
+ <Outlet />
699
+ </IntlayerProvider>
700
+ );
701
+ }
702
+
703
+ // NotFoundLayout оборачивает компонент 404 в IntlayerProvider
704
+ // Это гарантирует, что переводы все еще работают на странице 404
705
+ function NotFoundLayout() {
706
+ const { defaultLocale } = useLocale();
707
+ const { locale } = Route.useParams();
708
+
709
+ return (
710
+ <IntlayerProvider locale={locale ?? defaultLocale}>
711
+ <NotFoundComponent />
712
+ {/* Включить LocaleSwitcher, чтобы пользователи могли менять язык даже на 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
+ // Маршрут $ (splat/catch-all) соответствует любому пути, который не соответствует другим маршрутам
725
+ // например, /en/какой-то/глубоко/вложенный/недействительный/путь
726
+ // Это гарантирует, что ВСЕ несоответствующие пути в локали показывают страницу 404
727
+ // Без этого несоответствующие глубокие пути могут показать пустую страницу или ошибку
728
+ export const Route = createFileRoute("/{-$locale}/$")({
729
+ component: NotFoundComponent,
730
+ });
731
+ ```
732
+
733
+ ---
734
+
735
+ ### Шаг 15: Настройка TypeScript (необязательно)
606
736
 
607
737
  Intlayer использует расширение модулей (module augmentation), чтобы использовать преимущества TypeScript и сделать вашу кодовую базу более надежной.
608
738
 
@@ -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'i tanıt ve 14. adımı ekle: Yerelleştirilmiş rotalarla 404 sayfalarını ele alma.
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. adımı ekle: Sunucu işlemlerinde locale bilgisini almak (Opsiyonel)
25
28
  - version: 6.5.2
26
29
  date: 2025-10-03
27
30
  changes: Doküman güncellemesi
@@ -604,7 +607,134 @@ export const getLocaleServer = createServerFn().handler(async () => {
604
607
 
605
608
  ---
606
609
 
607
- ### Adım 14: TypeScript Yapılandırması (İsteğe Bağlı)
610
+ ### Adım 14: Bulunamayan sayfaları yönetme (İsteğe Bağlı)
611
+
612
+ Bir kullanıcı var olmayan bir sayfayı ziyaret ettiğinde, özel bir bulunamadı sayfası gösterebilirsiniz ve yerel ayar öneki, bulunamadı sayfasının tetiklenme şeklini etkileyebilir.
613
+
614
+ #### TanStack Router'ın Yerel Ayar Önekleriyle 404 İşlemesini Anlama
615
+
616
+ TanStack Router'da yerelleştirilmiş rotalarla 404 sayfalarını işlemek, çok katmanlı bir yaklaşım gerektirir:
617
+
618
+ 1. **Özel 404 rotası**: 404 kullanıcı arayüzünü göstermek için özel bir rota
619
+ 2. **Rota düzeyinde doğrulama**: Yerel ayar öneklerini doğrular ve geçersiz olanları 404'e yönlendirir
620
+ 3. **Catch-all rotası**: Yerel ayar segmenti içindeki eşleşmeyen tüm yolları yakalar
621
+
622
+ ```tsx fileName="src/routes/{-$locale}/404.tsx"
623
+ import { createFileRoute } from "@tanstack/react-router";
624
+
625
+ // Bu, özel bir /[locale]/404 rotası oluşturur
626
+ // Hem doğrudan bir rota olarak kullanılır hem de diğer dosyalarda bir bileşen olarak içe aktarılır
627
+ export const Route = createFileRoute("/{-$locale}/404")({
628
+ component: NotFoundComponent,
629
+ });
630
+
631
+ // notFoundComponent ve catch-all rotalarında yeniden kullanılabilmesi için ayrı olarak dışa aktarılır
632
+ export function NotFoundComponent() {
633
+ return (
634
+ <div>
635
+ <h1>404</h1>
636
+ </div>
637
+ );
638
+ }
639
+ ```
640
+
641
+ ```tsx fileName="src/routes/__root.tsx"
642
+ import { createRootRoute } from "@tanstack/react-router";
643
+
644
+ // Kök rota, en üst düzey düzen olarak hizmet eder
645
+ // 404'leri doğrudan işlemez - bu, alt rotalara devredilir
646
+ // Bu, kökü basit tutar ve yerel ayar farkında rotaların kendi 404 mantığını yönetmesine izin verir
647
+ export const Route = createRootRoute({
648
+ component: Outlet,
649
+ });
650
+ ```
651
+
652
+ ```tsx fileName="src/routes/{-$locale}/route.tsx"
653
+ import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
654
+ import { validatePrefix } from "intlayer";
655
+ import { IntlayerProvider, useLocale } from "react-intlayer";
656
+
657
+ import { LocaleSwitcher } from "@/components/locale-switcher";
658
+ import { NotFoundComponent } from "./404";
659
+
660
+ export const Route = createFileRoute("/{-$locale}")({
661
+ // beforeLoad, rota render edilmeden önce çalışır (hem sunucuda hem de istemcide)
662
+ // Yerel ayar önekini doğrulamak için ideal yerdir
663
+ beforeLoad: ({ params }) => {
664
+ // Yerel ayarı rota parametrelerinden al (sunucu başlıklarından değil, çünkü beforeLoad hem istemcide hem de sunucuda çalışır)
665
+ const localeParam = params.locale;
666
+
667
+ // validatePrefix, yerel ayarın intlayer yapılandırmanıza göre geçerli olup olmadığını kontrol eder
668
+ // Döndürür: { isValid: boolean, localePrefix: string }
669
+ // - isValid: önek yapılandırılmış bir yerel ayarla eşleşiyorsa (veya önek isteğe bağlı olduğunda boşsa) true
670
+ // - localePrefix: doğrulanmış önek veya yönlendirmeler için varsayılan yerel ayar öneki
671
+ const { isValid, localePrefix } = validatePrefix(localeParam);
672
+
673
+ if (isValid) {
674
+ // Yerel ayar geçerli, rotanın normal şekilde render edilmesine izin ver
675
+ return;
676
+ }
677
+
678
+ // Geçersiz yerel ayar öneki (örn. "xyz" geçerli bir yerel ayar olmadığında /xyz/about)
679
+ // Geçerli bir yerel ayar öneki ile 404 sayfasına yönlendir
680
+ // Bu, 404 sayfasının hala düzgün şekilde yerelleştirildiğini garanti eder
681
+ throw redirect({
682
+ to: "/{-$locale}/404",
683
+ params: { locale: localePrefix },
684
+ });
685
+ },
686
+ component: RouteComponent,
687
+ // notFoundComponent, bir alt rota mevcut olmadığında çağrılır
688
+ // örn. /en/var-olmayan-sayfa bunu /en düzeni içinde tetikler
689
+ notFoundComponent: NotFoundLayout,
690
+ });
691
+
692
+ function RouteComponent() {
693
+ const { defaultLocale } = useLocale();
694
+ const { locale } = Route.useParams();
695
+
696
+ return (
697
+ // Tüm yerel ayar segmentini IntlayerProvider ile sar
698
+ // Yerel ayar parametresi undefined olduğunda defaultLocale'e geri döner (isteğe bağlı önek modu)
699
+ <IntlayerProvider locale={locale ?? defaultLocale}>
700
+ <Outlet />
701
+ </IntlayerProvider>
702
+ );
703
+ }
704
+
705
+ // NotFoundLayout, 404 bileşenini IntlayerProvider ile sarar
706
+ // Bu, çevirilerin 404 sayfasında hala çalışmasını sağlar
707
+ function NotFoundLayout() {
708
+ const { defaultLocale } = useLocale();
709
+ const { locale } = Route.useParams();
710
+
711
+ return (
712
+ <IntlayerProvider locale={locale ?? defaultLocale}>
713
+ <NotFoundComponent />
714
+ {/* Kullanıcıların 404'te bile dil değiştirebilmesi için LocaleSwitcher'ı dahil et */}
715
+ <LocaleSwitcher />
716
+ </IntlayerProvider>
717
+ );
718
+ }
719
+ ```
720
+
721
+ ```tsx fileName="src/routes/{-$locale}/$.tsx"
722
+ import { createFileRoute } from "@tanstack/react-router";
723
+
724
+ import { NotFoundComponent } from "./404";
725
+
726
+ // $ (splat/catch-all) rotası, diğer rotalarla eşleşmeyen herhangi bir yolu eşleştirir
727
+ // örn. /en/bazı/derin/iç içe/geçersiz/yol
728
+ // Bu, bir yerel ayar içindeki TÜM eşleşmeyen yolların 404 sayfasını göstermesini sağlar
729
+ // Bu olmadan, eşleşmeyen derin yollar boş bir sayfa veya hata gösterebilir
730
+ export const Route = createFileRoute("/{-$locale}/$")({
731
+ component: NotFoundComponent,
732
+ });
733
+ ```
734
+
735
+ ---
736
+
737
+ ### Adım 15: TypeScript Yapılandırması (İsteğe Bağlı)
608
738
 
609
739
  Intlayer, TypeScript'in avantajlarından yararlanmak ve kod tabanınızı daha güçlü hale getirmek için modül genişletme (module augmentation) kullanır.
610
740
 
@@ -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: Giới thiệu validatePrefix và thêm bước 14: Xử lý trang 404 với các tuyến đường được bản địa hóa.
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: Thêm bước 13: Lấy locale trong server actions của bạn (Tùy chọn)
25
28
  - version: 6.5.2
26
29
  date: 2025-10-03
27
30
  changes: Cập nhật tài liệu
@@ -600,7 +603,134 @@ export const getLocaleServer = createServerFn().handler(async () => {
600
603
 
601
604
  ---
602
605
 
603
- ### Bước 14: Cấu hình TypeScript (Tùy chọn)
606
+ ### Bước 14: Quản trang không tìm thấy (Tùy chọn)
607
+
608
+ Khi người dùng truy cập một trang không tồn tại, bạn có thể hiển thị một trang không tìm thấy tùy chỉnh và tiền tố locale có thể ảnh hưởng đến cách trang không tìm thấy được kích hoạt.
609
+
610
+ #### Hiểu về xử lý 404 của TanStack Router với tiền tố locale
611
+
612
+ Trong TanStack Router, xử lý các trang 404 với các route đã được bản địa hóa yêu cầu một cách tiếp cận nhiều lớp:
613
+
614
+ 1. **Route 404 chuyên dụng**: Một route cụ thể để hiển thị giao diện 404
615
+ 2. **Xác thực cấp route**: Xác thực các tiền tố locale và chuyển hướng các tiền tố không hợp lệ đến 404
616
+ 3. **Route catch-all**: Bắt tất cả các đường dẫn không khớp trong phân đoạn locale
617
+
618
+ ```tsx fileName="src/routes/{-$locale}/404.tsx"
619
+ import { createFileRoute } from "@tanstack/react-router";
620
+
621
+ // Điều này tạo một tuyến đường /[locale]/404 chuyên dụng
622
+ // Nó được sử dụng cả như một tuyến đường trực tiếp và được nhập như một thành phần trong các tệp khác
623
+ export const Route = createFileRoute("/{-$locale}/404")({
624
+ component: NotFoundComponent,
625
+ });
626
+
627
+ // Xuất riêng để có thể tái sử dụng trong notFoundComponent và các tuyến catch-all
628
+ export function NotFoundComponent() {
629
+ return (
630
+ <div>
631
+ <h1>404</h1>
632
+ </div>
633
+ );
634
+ }
635
+ ```
636
+
637
+ ```tsx fileName="src/routes/__root.tsx"
638
+ import { createRootRoute } from "@tanstack/react-router";
639
+
640
+ // Tuyến đường gốc phục vụ như bố cục cấp cao nhất
641
+ // Nó không xử lý 404 trực tiếp - điều đó được ủy quyền cho các tuyến đường con
642
+ // Điều này giữ cho gốc đơn giản và cho phép các tuyến đường nhận biết locale quản lý logic 404 của riêng chúng
643
+ export const Route = createRootRoute({
644
+ component: Outlet,
645
+ });
646
+ ```
647
+
648
+ ```tsx fileName="src/routes/{-$locale}/route.tsx"
649
+ import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
650
+ import { validatePrefix } from "intlayer";
651
+ import { IntlayerProvider, useLocale } from "react-intlayer";
652
+
653
+ import { LocaleSwitcher } from "@/components/locale-switcher";
654
+ import { NotFoundComponent } from "./404";
655
+
656
+ export const Route = createFileRoute("/{-$locale}")({
657
+ // beforeLoad chạy trước khi tuyến đường được kết xuất (trên cả máy chủ và máy khách)
658
+ // Đây là nơi lý tưởng để xác thực tiền tố locale
659
+ beforeLoad: ({ params }) => {
660
+ // Lấy locale từ tham số tuyến đường (không phải từ tiêu đề máy chủ, vì beforeLoad chạy trên cả máy khách và máy chủ)
661
+ const localeParam = params.locale;
662
+
663
+ // validatePrefix kiểm tra xem locale có hợp lệ theo cấu hình intlayer của bạn không
664
+ // Trả về: { isValid: boolean, localePrefix: string }
665
+ // - isValid: true nếu tiền tố khớp với locale đã cấu hình (hoặc trống khi tiền tố là tùy chọn)
666
+ // - localePrefix: tiền tố đã được xác thực hoặc tiền tố locale mặc định để chuyển hướng
667
+ const { isValid, localePrefix } = validatePrefix(localeParam);
668
+
669
+ if (isValid) {
670
+ // Locale hợp lệ, cho phép tuyến đường kết xuất bình thường
671
+ return;
672
+ }
673
+
674
+ // Tiền tố locale không hợp lệ (ví dụ: /xyz/about trong đó "xyz" không phải là locale hợp lệ)
675
+ // Chuyển hướng đến trang 404 với tiền tố locale hợp lệ
676
+ // Điều này đảm bảo trang 404 vẫn được bản địa hóa đúng cách
677
+ throw redirect({
678
+ to: "/{-$locale}/404",
679
+ params: { locale: localePrefix },
680
+ });
681
+ },
682
+ component: RouteComponent,
683
+ // notFoundComponent được gọi khi một tuyến đường con không tồn tại
684
+ // ví dụ: /en/trang-khong-ton-tai kích hoạt điều này trong bố cục /en
685
+ notFoundComponent: NotFoundLayout,
686
+ });
687
+
688
+ function RouteComponent() {
689
+ const { defaultLocale } = useLocale();
690
+ const { locale } = Route.useParams();
691
+
692
+ return (
693
+ // Bọc toàn bộ phân đoạn locale bằng IntlayerProvider
694
+ // Quay lại defaultLocale khi tham số locale là undefined (chế độ tiền tố tùy chọn)
695
+ <IntlayerProvider locale={locale ?? defaultLocale}>
696
+ <Outlet />
697
+ </IntlayerProvider>
698
+ );
699
+ }
700
+
701
+ // NotFoundLayout bọc thành phần 404 bằng IntlayerProvider
702
+ // Điều này đảm bảo bản dịch vẫn hoạt động trên trang 404
703
+ function NotFoundLayout() {
704
+ const { defaultLocale } = useLocale();
705
+ const { locale } = Route.useParams();
706
+
707
+ return (
708
+ <IntlayerProvider locale={locale ?? defaultLocale}>
709
+ <NotFoundComponent />
710
+ {/* Bao gồm LocaleSwitcher để người dùng có thể thay đổi ngôn ngữ ngay cả trên 404 */}
711
+ <LocaleSwitcher />
712
+ </IntlayerProvider>
713
+ );
714
+ }
715
+ ```
716
+
717
+ ```tsx fileName="src/routes/{-$locale}/$.tsx"
718
+ import { createFileRoute } from "@tanstack/react-router";
719
+
720
+ import { NotFoundComponent } from "./404";
721
+
722
+ // Tuyến đường $ (splat/catch-all) khớp với bất kỳ đường dẫn nào không khớp với các tuyến đường khác
723
+ // ví dụ: /en/mot/duong/dan/sau/long/khong-hop-le
724
+ // Điều này đảm bảo TẤT CẢ các đường dẫn không khớp trong một locale hiển thị trang 404
725
+ // Nếu không có điều này, các đường dẫn sâu không khớp có thể hiển thị trang trống hoặc lỗi
726
+ export const Route = createFileRoute("/{-$locale}/$")({
727
+ component: NotFoundComponent,
728
+ });
729
+ ```
730
+
731
+ ---
732
+
733
+ ### Bước 15: Cấu hình TypeScript (Tùy chọn)
604
734
 
605
735
  Intlayer sử dụng module augmentation để tận dụng các lợi ích của TypeScript và làm cho codebase của bạn mạnh mẽ hơn.
606
736