@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.
- package/docs/ar/intlayer_with_tanstack.md +132 -2
- package/docs/de/intlayer_with_tanstack.md +132 -2
- package/docs/en/intlayer_with_tanstack.md +131 -1
- package/docs/en-GB/intlayer_with_tanstack.md +131 -1
- package/docs/es/intlayer_with_tanstack.md +132 -2
- package/docs/fr/intlayer_with_tanstack.md +132 -2
- package/docs/hi/intlayer_with_tanstack.md +132 -2
- package/docs/id/intlayer_with_tanstack.md +132 -2
- package/docs/it/intlayer_with_tanstack.md +132 -2
- package/docs/ja/intlayer_with_tanstack.md +132 -2
- package/docs/ko/intlayer_with_tanstack.md +132 -2
- package/docs/pl/intlayer_with_tanstack.md +132 -2
- package/docs/pt/intlayer_with_tanstack.md +132 -2
- package/docs/ru/intlayer_with_tanstack.md +132 -2
- package/docs/tr/intlayer_with_tanstack.md +132 -2
- package/docs/vi/intlayer_with_tanstack.md +132 -2
- package/docs/zh/intlayer_with_tanstack.md +132 -2
- package/package.json +6 -6
|
@@ -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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
606
|
+
### Bước 14: Quản lý 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
|
|