@intlayer/docs 7.3.14 → 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.
Files changed (175) hide show
  1. package/blog/ar/intlayer_with_i18next.md +3 -0
  2. package/blog/ar/intlayer_with_next-i18next.md +3 -0
  3. package/blog/ar/intlayer_with_next-intl.md +3 -0
  4. package/blog/ar/intlayer_with_react-i18next.md +3 -0
  5. package/blog/ar/intlayer_with_react-intl.md +3 -0
  6. package/blog/ar/intlayer_with_vue-i18n.md +3 -0
  7. package/blog/de/intlayer_with_i18next.md +3 -0
  8. package/blog/de/intlayer_with_next-i18next.md +3 -0
  9. package/blog/de/intlayer_with_next-intl.md +3 -0
  10. package/blog/de/intlayer_with_react-i18next.md +3 -0
  11. package/blog/de/intlayer_with_react-intl.md +3 -0
  12. package/blog/de/intlayer_with_vue-i18n.md +3 -0
  13. package/blog/en/intlayer_with_i18next.md +7 -0
  14. package/blog/en/intlayer_with_next-i18next.md +3 -0
  15. package/blog/en/intlayer_with_next-intl.md +7 -0
  16. package/blog/en/intlayer_with_react-i18next.md +3 -0
  17. package/blog/en/intlayer_with_react-intl.md +3 -0
  18. package/blog/en/intlayer_with_vue-i18n.md +3 -0
  19. package/blog/en-GB/intlayer_with_i18next.md +3 -0
  20. package/blog/en-GB/intlayer_with_next-i18next.md +3 -0
  21. package/blog/en-GB/intlayer_with_next-intl.md +3 -0
  22. package/blog/en-GB/intlayer_with_react-i18next.md +3 -0
  23. package/blog/en-GB/intlayer_with_react-intl.md +3 -0
  24. package/blog/en-GB/intlayer_with_vue-i18n.md +3 -0
  25. package/blog/es/intlayer_with_i18next.md +3 -0
  26. package/blog/es/intlayer_with_next-i18next.md +3 -0
  27. package/blog/es/intlayer_with_next-intl.md +3 -0
  28. package/blog/es/intlayer_with_react-i18next.md +3 -0
  29. package/blog/es/intlayer_with_react-intl.md +3 -0
  30. package/blog/es/intlayer_with_vue-i18n.md +3 -0
  31. package/blog/fr/intlayer_with_i18next.md +3 -0
  32. package/blog/fr/intlayer_with_next-i18next.md +3 -0
  33. package/blog/fr/intlayer_with_next-intl.md +3 -0
  34. package/blog/fr/intlayer_with_react-i18next.md +3 -0
  35. package/blog/fr/intlayer_with_react-intl.md +3 -0
  36. package/blog/fr/intlayer_with_vue-i18n.md +3 -0
  37. package/blog/hi/intlayer_with_i18next.md +3 -0
  38. package/blog/hi/intlayer_with_next-i18next.md +3 -0
  39. package/blog/hi/intlayer_with_next-intl.md +3 -0
  40. package/blog/hi/intlayer_with_react-i18next.md +3 -0
  41. package/blog/hi/intlayer_with_react-intl.md +3 -0
  42. package/blog/hi/intlayer_with_vue-i18n.md +3 -0
  43. package/blog/id/intlayer_with_i18next.md +3 -0
  44. package/blog/id/intlayer_with_next-i18next.md +3 -0
  45. package/blog/id/intlayer_with_next-intl.md +3 -0
  46. package/blog/id/intlayer_with_react-i18next.md +3 -0
  47. package/blog/id/intlayer_with_react-intl.md +3 -0
  48. package/blog/id/intlayer_with_vue-i18n.md +3 -0
  49. package/blog/it/intlayer_with_i18next.md +3 -0
  50. package/blog/it/intlayer_with_next-i18next.md +3 -0
  51. package/blog/it/intlayer_with_next-intl.md +3 -0
  52. package/blog/it/intlayer_with_react-i18next.md +3 -0
  53. package/blog/it/intlayer_with_react-intl.md +3 -0
  54. package/blog/it/intlayer_with_vue-i18n.md +3 -0
  55. package/blog/ja/intlayer_with_i18next.md +3 -0
  56. package/blog/ja/intlayer_with_next-i18next.md +3 -0
  57. package/blog/ja/intlayer_with_next-intl.md +3 -0
  58. package/blog/ja/intlayer_with_react-i18next.md +3 -0
  59. package/blog/ja/intlayer_with_react-intl.md +3 -0
  60. package/blog/ja/intlayer_with_vue-i18n.md +3 -0
  61. package/blog/ko/intlayer_with_i18next.md +3 -0
  62. package/blog/ko/intlayer_with_next-i18next.md +3 -0
  63. package/blog/ko/intlayer_with_next-intl.md +3 -0
  64. package/blog/ko/intlayer_with_react-i18next.md +3 -0
  65. package/blog/ko/intlayer_with_react-intl.md +3 -0
  66. package/blog/ko/intlayer_with_vue-i18n.md +3 -0
  67. package/blog/pl/intlayer_with_i18next.md +3 -0
  68. package/blog/pl/intlayer_with_next-i18next.md +3 -0
  69. package/blog/pl/intlayer_with_next-intl.md +3 -0
  70. package/blog/pl/intlayer_with_react-i18next.md +3 -0
  71. package/blog/pl/intlayer_with_react-intl.md +3 -0
  72. package/blog/pl/intlayer_with_vue-i18n.md +3 -0
  73. package/blog/pt/intlayer_with_i18next.md +3 -0
  74. package/blog/pt/intlayer_with_next-i18next.md +3 -0
  75. package/blog/pt/intlayer_with_next-intl.md +3 -0
  76. package/blog/pt/intlayer_with_react-i18next.md +3 -0
  77. package/blog/pt/intlayer_with_react-intl.md +3 -0
  78. package/blog/pt/intlayer_with_vue-i18n.md +3 -0
  79. package/blog/ru/intlayer_with_i18next.md +3 -0
  80. package/blog/ru/intlayer_with_next-i18next.md +3 -0
  81. package/blog/ru/intlayer_with_next-intl.md +3 -0
  82. package/blog/ru/intlayer_with_react-i18next.md +3 -0
  83. package/blog/ru/intlayer_with_react-intl.md +3 -0
  84. package/blog/ru/intlayer_with_vue-i18n.md +3 -0
  85. package/blog/tr/intlayer_with_i18next.md +3 -0
  86. package/blog/tr/intlayer_with_next-i18next.md +3 -0
  87. package/blog/tr/intlayer_with_next-intl.md +3 -0
  88. package/blog/tr/intlayer_with_react-i18next.md +3 -0
  89. package/blog/tr/intlayer_with_vue-i18n.md +3 -0
  90. package/blog/vi/intlayer_with_i18next.md +3 -0
  91. package/blog/vi/intlayer_with_next-i18next.md +3 -0
  92. package/blog/vi/intlayer_with_next-intl.md +3 -0
  93. package/blog/vi/intlayer_with_react-i18next.md +3 -0
  94. package/blog/vi/intlayer_with_react-intl.md +3 -0
  95. package/blog/vi/intlayer_with_vue-i18n.md +3 -0
  96. package/blog/zh/intlayer_with_i18next.md +3 -0
  97. package/blog/zh/intlayer_with_next-i18next.md +3 -0
  98. package/blog/zh/intlayer_with_next-intl.md +3 -0
  99. package/blog/zh/intlayer_with_react-i18next.md +3 -0
  100. package/blog/zh/intlayer_with_react-intl.md +3 -0
  101. package/blog/zh/intlayer_with_vue-i18n.md +3 -0
  102. package/docs/ar/intlayer_with_lynx+react.md +1 -1
  103. package/docs/ar/intlayer_with_tanstack.md +132 -2
  104. package/docs/ar/intlayer_with_vite+react.md +99 -331
  105. package/docs/ar/plugins/sync-json.md +3 -0
  106. package/docs/de/intlayer_with_lynx+react.md +1 -1
  107. package/docs/de/intlayer_with_tanstack.md +132 -2
  108. package/docs/de/intlayer_with_vite+react.md +116 -380
  109. package/docs/de/plugins/sync-json.md +3 -0
  110. package/docs/en/intlayer_with_tanstack.md +131 -1
  111. package/docs/en/intlayer_with_vite+react.md +6 -10
  112. package/docs/en/plugins/sync-json.md +3 -0
  113. package/docs/en-GB/intlayer_with_tanstack.md +131 -1
  114. package/docs/en-GB/intlayer_with_vite+react.md +62 -74
  115. package/docs/en-GB/plugins/sync-json.md +3 -0
  116. package/docs/es/intlayer_with_tanstack.md +132 -2
  117. package/docs/es/intlayer_with_vite+react.md +101 -333
  118. package/docs/es/plugins/sync-json.md +3 -0
  119. package/docs/fr/intlayer_with_tanstack.md +132 -2
  120. package/docs/fr/intlayer_with_vite+react.md +101 -357
  121. package/docs/fr/plugins/sync-json.md +3 -0
  122. package/docs/hi/intlayer_with_tanstack.md +132 -2
  123. package/docs/hi/intlayer_with_vite+react.md +120 -333
  124. package/docs/hi/plugins/sync-json.md +3 -0
  125. package/docs/id/intlayer_with_tanstack.md +132 -2
  126. package/docs/id/intlayer_with_vite+react.md +7 -13
  127. package/docs/id/plugins/sync-json.md +3 -0
  128. package/docs/it/intlayer_with_lynx+react.md +1 -1
  129. package/docs/it/intlayer_with_tanstack.md +132 -2
  130. package/docs/it/intlayer_with_vite+react.md +121 -393
  131. package/docs/it/plugins/sync-json.md +3 -0
  132. package/docs/ja/intlayer_with_tanstack.md +132 -2
  133. package/docs/ja/intlayer_with_vite+react.md +106 -378
  134. package/docs/ja/plugins/sync-json.md +3 -0
  135. package/docs/ko/intlayer_with_lynx+react.md +1 -1
  136. package/docs/ko/intlayer_with_tanstack.md +132 -2
  137. package/docs/ko/intlayer_with_vite+react.md +90 -322
  138. package/docs/ko/plugins/sync-json.md +3 -0
  139. package/docs/pl/intlayer_with_tanstack.md +132 -2
  140. package/docs/pl/intlayer_with_vite+react.md +25 -21
  141. package/docs/pl/plugins/sync-json.md +3 -0
  142. package/docs/pt/intlayer_with_tanstack.md +132 -2
  143. package/docs/pt/intlayer_with_vite+react.md +96 -328
  144. package/docs/pt/plugins/sync-json.md +3 -0
  145. package/docs/ru/intlayer_with_lynx+react.md +1 -1
  146. package/docs/ru/intlayer_with_tanstack.md +132 -2
  147. package/docs/ru/intlayer_with_vite+react.md +109 -362
  148. package/docs/ru/plugins/sync-json.md +3 -0
  149. package/docs/tr/intlayer_with_tanstack.md +132 -2
  150. package/docs/tr/intlayer_with_vite+react.md +132 -366
  151. package/docs/tr/plugins/sync-json.md +3 -0
  152. package/docs/vi/intlayer_with_tanstack.md +132 -2
  153. package/docs/vi/intlayer_with_vite+react.md +16 -19
  154. package/docs/vi/plugins/sync-json.md +3 -0
  155. package/docs/zh/intlayer_with_tanstack.md +133 -3
  156. package/docs/zh/intlayer_with_vite+react.md +91 -374
  157. package/docs/zh/plugins/sync-json.md +3 -0
  158. package/frequent_questions/ar/customized_locale_list.md +1 -1
  159. package/frequent_questions/de/customized_locale_list.md +1 -1
  160. package/frequent_questions/en/customized_locale_list.md +1 -1
  161. package/frequent_questions/en-GB/customized_locale_list.md +1 -1
  162. package/frequent_questions/es/customized_locale_list.md +1 -1
  163. package/frequent_questions/fr/customized_locale_list.md +1 -1
  164. package/frequent_questions/hi/customized_locale_list.md +1 -1
  165. package/frequent_questions/id/customized_locale_list.md +1 -1
  166. package/frequent_questions/it/customized_locale_list.md +1 -1
  167. package/frequent_questions/ja/customized_locale_list.md +1 -1
  168. package/frequent_questions/ko/customized_locale_list.md +1 -1
  169. package/frequent_questions/pl/customized_locale_list.md +1 -1
  170. package/frequent_questions/pt/customized_locale_list.md +1 -1
  171. package/frequent_questions/ru/customized_locale_list.md +1 -1
  172. package/frequent_questions/tr/customized_locale_list.md +1 -1
  173. package/frequent_questions/vi/customized_locale_list.md +1 -1
  174. package/frequent_questions/zh/customized_locale_list.md +1 -1
  175. 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: Внедрена 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