@intlayer/docs 8.6.1 → 8.6.10

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 (197) hide show
  1. package/dist/cjs/doc.cjs.map +1 -1
  2. package/dist/cjs/generated/docs.entry.cjs +60 -0
  3. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  4. package/dist/esm/doc.mjs.map +1 -1
  5. package/dist/esm/generated/docs.entry.mjs +60 -0
  6. package/dist/esm/generated/docs.entry.mjs.map +1 -1
  7. package/dist/types/doc.d.ts.map +1 -1
  8. package/dist/types/generated/docs.entry.d.ts +3 -0
  9. package/dist/types/generated/docs.entry.d.ts.map +1 -1
  10. package/docs/ar/cli/index.md +54 -42
  11. package/docs/ar/cli/init.md +32 -20
  12. package/docs/ar/cli/standalone.md +91 -0
  13. package/docs/ar/configuration.md +39 -7
  14. package/docs/ar/custom_domains.md +250 -0
  15. package/docs/ar/intlayer_with_tanstack+solid.md +14 -33
  16. package/docs/ar/intlayer_with_tanstack.md +25 -16
  17. package/docs/ar/intlayer_with_vanilla.md +506 -0
  18. package/docs/bn/cli/index.md +195 -0
  19. package/docs/bn/cli/init.md +96 -0
  20. package/docs/bn/cli/standalone.md +91 -0
  21. package/docs/bn/configuration.md +46 -14
  22. package/docs/bn/custom_domains.md +250 -0
  23. package/docs/bn/intlayer_with_vanilla.md +506 -0
  24. package/docs/cs/cli/index.md +195 -0
  25. package/docs/cs/cli/init.md +96 -0
  26. package/docs/cs/cli/standalone.md +91 -0
  27. package/docs/cs/configuration.md +46 -7
  28. package/docs/cs/custom_domains.md +250 -0
  29. package/docs/cs/intlayer_with_vanilla.md +506 -0
  30. package/docs/de/cli/index.md +53 -41
  31. package/docs/de/cli/standalone.md +91 -0
  32. package/docs/de/configuration.md +46 -7
  33. package/docs/de/custom_domains.md +250 -0
  34. package/docs/de/intlayer_with_tanstack+solid.md +14 -33
  35. package/docs/de/intlayer_with_tanstack.md +25 -16
  36. package/docs/de/intlayer_with_vanilla.md +506 -0
  37. package/docs/en/bundle_optimization.md +288 -23
  38. package/docs/en/cli/index.md +6 -1
  39. package/docs/en/cli/init.md +13 -1
  40. package/docs/en/cli/standalone.md +91 -0
  41. package/docs/en/configuration.md +46 -7
  42. package/docs/en/custom_domains.md +245 -0
  43. package/docs/en/intlayer_with_tanstack+solid.md +14 -33
  44. package/docs/en/intlayer_with_tanstack.md +25 -16
  45. package/docs/en/intlayer_with_vanilla.md +506 -0
  46. package/docs/en-GB/cli/index.md +56 -44
  47. package/docs/en-GB/cli/init.md +28 -21
  48. package/docs/en-GB/cli/standalone.md +91 -0
  49. package/docs/en-GB/configuration.md +53 -14
  50. package/docs/en-GB/custom_domains.md +250 -0
  51. package/docs/en-GB/intlayer_with_tanstack+solid.md +14 -33
  52. package/docs/en-GB/intlayer_with_tanstack.md +25 -16
  53. package/docs/en-GB/intlayer_with_vanilla.md +506 -0
  54. package/docs/es/cli/index.md +65 -53
  55. package/docs/es/cli/init.md +33 -21
  56. package/docs/es/cli/standalone.md +91 -0
  57. package/docs/es/configuration.md +39 -1
  58. package/docs/es/custom_domains.md +250 -0
  59. package/docs/es/intlayer_with_tanstack+solid.md +14 -33
  60. package/docs/es/intlayer_with_tanstack.md +25 -16
  61. package/docs/es/intlayer_with_vanilla.md +506 -0
  62. package/docs/fr/cli/index.md +43 -31
  63. package/docs/fr/cli/init.md +37 -25
  64. package/docs/fr/cli/standalone.md +91 -0
  65. package/docs/fr/configuration.md +46 -7
  66. package/docs/fr/custom_domains.md +250 -0
  67. package/docs/fr/intlayer_with_tanstack+solid.md +14 -33
  68. package/docs/fr/intlayer_with_tanstack.md +25 -16
  69. package/docs/fr/intlayer_with_vanilla.md +506 -0
  70. package/docs/hi/cli/index.md +71 -59
  71. package/docs/hi/cli/init.md +37 -33
  72. package/docs/hi/cli/standalone.md +91 -0
  73. package/docs/hi/configuration.md +39 -7
  74. package/docs/hi/custom_domains.md +250 -0
  75. package/docs/hi/intlayer_with_tanstack+solid.md +14 -33
  76. package/docs/hi/intlayer_with_tanstack.md +25 -16
  77. package/docs/hi/intlayer_with_vanilla.md +506 -0
  78. package/docs/id/cli/index.md +59 -47
  79. package/docs/id/cli/init.md +32 -25
  80. package/docs/id/cli/standalone.md +91 -0
  81. package/docs/id/configuration.md +46 -7
  82. package/docs/id/custom_domains.md +250 -0
  83. package/docs/id/intlayer_with_tanstack+solid.md +14 -33
  84. package/docs/id/intlayer_with_tanstack.md +25 -16
  85. package/docs/id/intlayer_with_vanilla.md +506 -0
  86. package/docs/it/cli/index.md +58 -41
  87. package/docs/it/cli/init.md +37 -38
  88. package/docs/it/cli/standalone.md +91 -0
  89. package/docs/it/configuration.md +46 -7
  90. package/docs/it/custom_domains.md +250 -0
  91. package/docs/it/intlayer_with_tanstack+solid.md +14 -33
  92. package/docs/it/intlayer_with_tanstack.md +25 -16
  93. package/docs/it/intlayer_with_vanilla.md +506 -0
  94. package/docs/ja/cli/index.md +59 -47
  95. package/docs/ja/cli/init.md +36 -24
  96. package/docs/ja/cli/standalone.md +91 -0
  97. package/docs/ja/configuration.md +46 -7
  98. package/docs/ja/custom_domains.md +250 -0
  99. package/docs/ja/intlayer_with_tanstack+solid.md +14 -33
  100. package/docs/ja/intlayer_with_tanstack.md +25 -16
  101. package/docs/ja/intlayer_with_vanilla.md +506 -0
  102. package/docs/ko/cli/index.md +58 -46
  103. package/docs/ko/cli/init.md +39 -35
  104. package/docs/ko/cli/standalone.md +91 -0
  105. package/docs/ko/configuration.md +47 -8
  106. package/docs/ko/custom_domains.md +250 -0
  107. package/docs/ko/intlayer_with_tanstack+solid.md +14 -33
  108. package/docs/ko/intlayer_with_tanstack.md +25 -16
  109. package/docs/ko/intlayer_with_vanilla.md +506 -0
  110. package/docs/nl/cli/index.md +195 -0
  111. package/docs/nl/cli/init.md +96 -0
  112. package/docs/nl/cli/standalone.md +91 -0
  113. package/docs/nl/configuration.md +46 -7
  114. package/docs/nl/custom_domains.md +250 -0
  115. package/docs/nl/intlayer_with_vanilla.md +506 -0
  116. package/docs/pl/cli/index.md +56 -44
  117. package/docs/pl/cli/init.md +36 -32
  118. package/docs/pl/cli/standalone.md +91 -0
  119. package/docs/pl/configuration.md +46 -7
  120. package/docs/pl/custom_domains.md +250 -0
  121. package/docs/pl/intlayer_with_tanstack+solid.md +14 -33
  122. package/docs/pl/intlayer_with_tanstack.md +25 -16
  123. package/docs/pl/intlayer_with_vanilla.md +506 -0
  124. package/docs/pt/cli/index.md +64 -52
  125. package/docs/pt/cli/init.md +35 -31
  126. package/docs/pt/cli/standalone.md +91 -0
  127. package/docs/pt/configuration.md +46 -7
  128. package/docs/pt/custom_domains.md +250 -0
  129. package/docs/pt/intlayer_with_tanstack+solid.md +14 -33
  130. package/docs/pt/intlayer_with_tanstack.md +25 -16
  131. package/docs/pt/intlayer_with_vanilla.md +506 -0
  132. package/docs/ru/cli/index.md +54 -42
  133. package/docs/ru/cli/init.md +31 -27
  134. package/docs/ru/cli/standalone.md +91 -0
  135. package/docs/ru/configuration.md +46 -7
  136. package/docs/ru/custom_domains.md +250 -0
  137. package/docs/ru/intlayer_with_tanstack+solid.md +14 -33
  138. package/docs/ru/intlayer_with_tanstack.md +25 -16
  139. package/docs/ru/intlayer_with_vanilla.md +506 -0
  140. package/docs/tr/cli/index.md +64 -52
  141. package/docs/tr/cli/init.md +37 -30
  142. package/docs/tr/cli/standalone.md +91 -0
  143. package/docs/tr/configuration.md +46 -7
  144. package/docs/tr/custom_domains.md +250 -0
  145. package/docs/tr/intlayer_with_tanstack+solid.md +14 -33
  146. package/docs/tr/intlayer_with_tanstack.md +25 -16
  147. package/docs/tr/intlayer_with_vanilla.md +506 -0
  148. package/docs/uk/cli/index.md +60 -55
  149. package/docs/uk/cli/init.md +32 -20
  150. package/docs/uk/cli/standalone.md +91 -0
  151. package/docs/uk/configuration.md +46 -7
  152. package/docs/uk/custom_domains.md +250 -0
  153. package/docs/uk/intlayer_with_tanstack+solid.md +14 -33
  154. package/docs/uk/intlayer_with_tanstack.md +25 -16
  155. package/docs/uk/intlayer_with_vanilla.md +506 -0
  156. package/docs/ur/cli/index.md +195 -0
  157. package/docs/ur/cli/init.md +96 -0
  158. package/docs/ur/cli/standalone.md +91 -0
  159. package/docs/ur/configuration.md +46 -7
  160. package/docs/ur/custom_domains.md +250 -0
  161. package/docs/ur/intlayer_with_vanilla.md +506 -0
  162. package/docs/vi/cli/index.md +72 -61
  163. package/docs/vi/cli/init.md +33 -21
  164. package/docs/vi/cli/standalone.md +91 -0
  165. package/docs/vi/configuration.md +46 -7
  166. package/docs/vi/custom_domains.md +250 -0
  167. package/docs/vi/intlayer_with_tanstack+solid.md +14 -33
  168. package/docs/vi/intlayer_with_tanstack.md +25 -16
  169. package/docs/vi/intlayer_with_vanilla.md +506 -0
  170. package/docs/zh/cli/index.md +56 -49
  171. package/docs/zh/cli/init.md +30 -18
  172. package/docs/zh/cli/standalone.md +91 -0
  173. package/docs/zh/configuration.md +46 -7
  174. package/docs/zh/custom_domains.md +250 -0
  175. package/docs/zh/intlayer_with_tanstack+solid.md +14 -33
  176. package/docs/zh/intlayer_with_tanstack.md +25 -16
  177. package/docs/zh/intlayer_with_vanilla.md +506 -0
  178. package/package.json +8 -8
  179. package/src/doc.ts +4 -1
  180. package/src/generated/docs.entry.ts +60 -0
  181. package/docs/ar/bundle_optimization.md +0 -185
  182. package/docs/de/bundle_optimization.md +0 -195
  183. package/docs/en-GB/bundle_optimization.md +0 -184
  184. package/docs/es/bundle_optimization.md +0 -194
  185. package/docs/fr/bundle_optimization.md +0 -184
  186. package/docs/hi/bundle_optimization.md +0 -185
  187. package/docs/id/bundle_optimization.md +0 -185
  188. package/docs/it/bundle_optimization.md +0 -185
  189. package/docs/ja/bundle_optimization.md +0 -185
  190. package/docs/ko/bundle_optimization.md +0 -185
  191. package/docs/pl/bundle_optimization.md +0 -185
  192. package/docs/pt/bundle_optimization.md +0 -184
  193. package/docs/ru/bundle_optimization.md +0 -185
  194. package/docs/tr/bundle_optimization.md +0 -184
  195. package/docs/uk/bundle_optimization.md +0 -186
  196. package/docs/vi/bundle_optimization.md +0 -185
  197. package/docs/zh/bundle_optimization.md +0 -185
@@ -0,0 +1,245 @@
1
+ ---
2
+ createdAt: 2026-04-03
3
+ updatedAt: 2026-04-03
4
+ title: Custom Domains
5
+ description: Configure domain-based locale routing in Intlayer to serve different locales from dedicated hostnames.
6
+ keywords:
7
+ - Custom Domains
8
+ - Domain Routing
9
+ - Routing
10
+ - Internationalization
11
+ - i18n
12
+ slugs:
13
+ - doc
14
+ - concept
15
+ - custom_domains
16
+ history:
17
+ - version: 8.7.0
18
+ date: 2026-04-03
19
+ changes: "Add domain-based locale routing via routing.domains configuration."
20
+ ---
21
+
22
+ # Custom Domains
23
+
24
+ Intlayer supports domain-based locale routing, allowing you to serve specific locales from dedicated hostnames. For example, Chinese visitors can be directed to `intlayer.zh` instead of `intlayer.org/zh`.
25
+
26
+ ## How It Works
27
+
28
+ The `domains` map in `routing` associates each locale with a hostname. Intlayer uses this map in two places:
29
+
30
+ 1. **URL generation** (`getLocalizedUrl`): when the target locale lives on a _different_ domain than the current page, an absolute URL is returned (e.g. `https://intlayer.zh/about`). When both domains match, a relative URL is returned (e.g. `/fr/about`).
31
+ 2. **Server proxy** (Next.js & Vite): incoming requests are redirected or rewritten based on the domain they arrive on.
32
+
33
+ ### Exclusive vs. shared domains
34
+
35
+ The key distinction is **exclusivity**:
36
+
37
+ - **Exclusive domain** — only one locale maps to that hostname (e.g. `zh → intlayer.zh`). The domain itself identifies the locale, so no locale prefix is added to the path. `https://intlayer.zh/about` serves Chinese content.
38
+ - **Shared domain** — multiple locales map to the same hostname (e.g. `en` and `fr` both map to `intlayer.org`). Normal prefix-based routing applies. `intlayer.org/fr/about` serves French content.
39
+
40
+ ## Configuration
41
+
42
+ ```typescript fileName="intlayer.config.ts"
43
+ import { Locales, type IntlayerConfig } from "intlayer";
44
+
45
+ const config: IntlayerConfig = {
46
+ internationalization: {
47
+ locales: [Locales.ENGLISH, Locales.FRENCH, Locales.CHINESE],
48
+ defaultLocale: Locales.ENGLISH,
49
+ },
50
+ routing: {
51
+ mode: "prefix-no-default",
52
+ domains: {
53
+ // Shared domain — en and fr use prefix routing on intlayer.org
54
+ en: "intlayer.org",
55
+ // Exclusive domain — zh has its own hostname, no /zh/ prefix needed
56
+ zh: "intlayer.zh",
57
+ },
58
+ },
59
+ };
60
+
61
+ export default config;
62
+ ```
63
+
64
+ Locales that are not listed in `domains` continue to use the standard prefix routing without any domain override.
65
+
66
+ ## URL Generation
67
+
68
+ `getLocalizedUrl` automatically produces the correct URL type based on the calling context.
69
+
70
+ ### Same-domain locale (relative URL)
71
+
72
+ ```ts
73
+ // Current page: intlayer.org/about
74
+ getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.org" });
75
+ // → "/fr/about"
76
+
77
+ getLocalizedUrl("/about", "en", { currentDomain: "intlayer.org" });
78
+ // → "/about" (default locale, no prefix)
79
+ ```
80
+
81
+ ### Cross-domain locale (absolute URL)
82
+
83
+ ```ts
84
+ // Current page: intlayer.org/about
85
+ getLocalizedUrl("/about", "zh", { currentDomain: "intlayer.org" });
86
+ // → "https://intlayer.zh/about" (exclusive domain, no /zh/ prefix)
87
+ ```
88
+
89
+ ### Serving from the locale's own domain
90
+
91
+ ```ts
92
+ // Current page: intlayer.zh/about
93
+ getLocalizedUrl("/about", "zh", { currentDomain: "intlayer.zh" });
94
+ // → "/about" (already on the correct domain — relative URL)
95
+
96
+ getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.zh" });
97
+ // → "https://intlayer.org/fr/about" (cross-domain link back to intlayer.org)
98
+ ```
99
+
100
+ ### Current domain auto-detection
101
+
102
+ `currentDomain` is optional. When omitted, `getLocalizedUrl` resolves it in this order:
103
+
104
+ 1. The hostname of an absolute input URL (e.g. `https://intlayer.org/about` → `intlayer.org`).
105
+ 2. `window.location.hostname` in browser environments.
106
+ 3. If neither is available (SSR without explicit option), a relative URL is returned for same-domain locales and no absolute URL is produced — this is the safe fallback.
107
+
108
+ ```ts
109
+ // Browser — window.location.hostname === 'intlayer.org'
110
+ getLocalizedUrl("/about", "zh");
111
+ // → "https://intlayer.zh/about" (auto-detected from window)
112
+
113
+ // From an absolute URL — domain detected automatically
114
+ getLocalizedUrl("https://intlayer.org/about", "zh");
115
+ // → "https://intlayer.zh/about"
116
+ ```
117
+
118
+ ### `getMultilingualUrls` with domains
119
+
120
+ `getMultilingualUrls` calls `getLocalizedUrl` for every locale, so it produces a mix of relative and absolute URLs depending on the caller's domain:
121
+
122
+ ```ts
123
+ // currentDomain: 'intlayer.org'
124
+ getMultilingualUrls("/about", { currentDomain: "intlayer.org" });
125
+ // {
126
+ // en: "/about",
127
+ // fr: "/fr/about",
128
+ // es: "/es/about",
129
+ // zh: "https://intlayer.zh/about",
130
+ // }
131
+ ```
132
+
133
+ These absolute URLs are ready to use in `<link rel="alternate" hreflang="...">` tags for SEO.
134
+
135
+ ## Proxy Behaviour
136
+
137
+ ### Next.js
138
+
139
+ The `intlayerProxy` middleware handles domain routing automatically. Add it to your `middleware.ts`:
140
+
141
+ ```typescript fileName="middleware.ts"
142
+ export { intlayerProxy as default } from "next-intlayer/proxy";
143
+
144
+ export const config = {
145
+ matcher: "/((?!api|static|assets|robots|sitemap|.*\\..*|_next).*)",
146
+ };
147
+ ```
148
+
149
+ **Redirect** — request arrives on the wrong domain for a given locale prefix:
150
+
151
+ ```
152
+ GET intlayer.org/zh/about
153
+ → 301 https://intlayer.zh/about
154
+ ```
155
+
156
+ **Rewrite** — request arrives on the locale's exclusive domain without a prefix:
157
+
158
+ ```
159
+ GET intlayer.zh/about
160
+ → rewrite to /zh/about (internal Next.js routing only, URL stays clean)
161
+ ```
162
+
163
+ ### Vite
164
+
165
+ The `intlayerProxy` Vite plugin applies the same logic during development:
166
+
167
+ ```typescript fileName="vite.config.ts"
168
+ import { defineConfig } from "vite";
169
+ import { intlayerProxy } from "vite-intlayer";
170
+
171
+ export default defineConfig({
172
+ plugins: [intlayerProxy()],
173
+ });
174
+ ```
175
+
176
+ > **Note**: in local development you are typically on `localhost`, so cross-domain redirects will point to the live domains rather than another local port. Use a hosts-file override (e.g. `127.0.0.1 intlayer.zh`) or a reverse proxy if you need to test multi-domain routing locally.
177
+
178
+ ## Locale Switcher
179
+
180
+ The `useLocale` hook from `next-intlayer` handles domain-aware navigation automatically. When a user switches to a locale on a different domain the hook performs a full-page navigation (`window.location.href`) instead of a client-side router push, because the Next.js router cannot cross origins.
181
+
182
+ ```tsx fileName="components/LocaleSwitcher.tsx"
183
+ "use client";
184
+
185
+ import { useLocale } from "next-intlayer";
186
+
187
+ export const LocaleSwitcher = () => {
188
+ const { availableLocales, locale, setLocale } = useLocale();
189
+
190
+ return (
191
+ <ul>
192
+ {availableLocales.map((localeEl) => (
193
+ <li key={localeEl}>
194
+ <button
195
+ onClick={() => setLocale(localeEl)}
196
+ aria-current={localeEl === locale ? "true" : undefined}
197
+ >
198
+ {localeEl.toUpperCase()}
199
+ </button>
200
+ </li>
201
+ ))}
202
+ </ul>
203
+ );
204
+ };
205
+ ```
206
+
207
+ No extra configuration is required — `useLocale` detects `window.location.hostname` internally and decides between `router.replace` (same domain) and `window.location.href` (cross-domain).
208
+
209
+ ## SEO: `hreflang` Alternate Links
210
+
211
+ Domain-based routing is commonly used together with `hreflang` to tell search engines which URL to index for each language. Use `getMultilingualUrls` to generate the full set of alternate URLs:
212
+
213
+ ```tsx fileName="app/[locale]/layout.tsx"
214
+ import { getMultilingualUrls } from "intlayer";
215
+ import type { Metadata } from "next";
216
+
217
+ export const generateMetadata = (): Metadata => {
218
+ const alternates = getMultilingualUrls("/", {
219
+ currentDomain: process.env.NEXT_PUBLIC_DOMAIN, // e.g. "intlayer.org"
220
+ });
221
+
222
+ return {
223
+ alternates: {
224
+ languages: alternates,
225
+ },
226
+ };
227
+ };
228
+ ```
229
+
230
+ This produces:
231
+
232
+ ```html
233
+ <link rel="alternate" hreflang="en" href="https://intlayer.org/" />
234
+ <link rel="alternate" hreflang="fr" href="https://intlayer.org/fr/" />
235
+ <link rel="alternate" hreflang="es" href="https://intlayer.org/es/" />
236
+ <link rel="alternate" hreflang="zh" href="https://intlayer.zh/" />
237
+ ```
238
+
239
+ ## Core Utilities
240
+
241
+ | Utility | Description |
242
+ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
243
+ | `getLocalizedUrl(url, locale, { currentDomain })` | Returns relative or absolute URL depending on whether the target locale is on the current domain. |
244
+ | `getMultilingualUrls(url, { currentDomain })` | Returns a locale-keyed map of localized URLs, mixing relative and absolute as needed. |
245
+ | `getPrefix(locale, { domains })` | Returns an empty prefix for exclusive-domain locales, normal prefix otherwise. |
@@ -17,6 +17,7 @@ slugs:
17
17
  - doc
18
18
  - environment
19
19
  - tanstack-start
20
+ - solid
20
21
  applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-solid-template
21
22
  youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
22
23
  history:
@@ -166,59 +167,45 @@ export default defineConfig({
166
167
 
167
168
  ### Step 5: Create Root Layout
168
169
 
169
- Configure your root layout to support internationalization by using `useMatches` to detect the current locale and setting the `lang` and `dir` attributes on the `html` tag.
170
+ Configure your root layout to support internationalization by using `useParams` to detect the current locale and setting the `lang` and `dir` attributes on the `html` tag.
170
171
 
171
172
  ```tsx fileName="src/routes/__root.tsx"
172
173
  import {
173
174
  HeadContent,
174
- Outlet,
175
175
  Scripts,
176
176
  createRootRouteWithContext,
177
- useMatches,
178
177
  } from "@tanstack/solid-router";
179
- import { TanStackRouterDevtools } from "@tanstack/solid-router-devtools";
180
178
  import { HydrationScript } from "solid-js/web";
181
- import { Suspense } from "solid-js";
179
+ import { Suspense, type ParentComponent } from "solid-js";
182
180
  import { IntlayerProvider } from "solid-intlayer";
183
- import { defaultLocale, getHTMLTextDir, type Locale } from "intlayer";
181
+ import { defaultLocale, getHTMLTextDir } from "intlayer";
182
+ import { Route as LocaleRoute } from "./{-$locale}/route";
184
183
 
185
184
  export const Route = createRootRouteWithContext()({
186
185
  shellComponent: RootComponent,
187
186
  });
188
187
 
189
- type Params = {
190
- locale: Locale;
191
- };
192
-
193
- function RootComponent() {
194
- const matches = useMatches();
195
-
196
- // Try to find locale in params of any active match
197
- // This assumes you use the dynamic segment "/{-$locale}" in your route tree
198
- const locale =
199
- (
200
- matches().find((match) => match.routeId === "/{-$locale}/")
201
- ?.params as Params
202
- )?.locale ?? defaultLocale;
188
+ const RootComponent: ParentComponent = (props) => {
189
+ const params = LocaleRoute.useParams();
190
+ const locale = params()?.locale ?? defaultLocale;
203
191
 
204
192
  return (
205
193
  <html dir={getHTMLTextDir(locale)} lang={locale}>
206
194
  <head>
207
195
  <HydrationScript />
196
+ <HeadContent />
208
197
  </head>
209
198
  <body>
210
- <HeadContent />
211
199
  <IntlayerProvider locale={locale}>
212
200
  <Suspense>
213
- <Outlet />
214
- <TanStackRouterDevtools />
201
+ {props.children}
215
202
  </Suspense>
216
203
  </IntlayerProvider>
217
204
  <Scripts />
218
205
  </body>
219
206
  </html>
220
207
  );
221
- }
208
+ };
222
209
  ```
223
210
 
224
211
  ### Step 6: Create Locale Layout (Optional)
@@ -462,18 +449,12 @@ export default LocaleSwitcher;
462
449
 
463
450
  ### Step 10: HTML Attributes Management
464
451
 
465
- As seen in Step 5, you can manage the `lang` and `dir` attributes of the `html` tag using `useMatches` in your root component. This ensures that the correct attributes are set on the server and client.
452
+ As seen in Step 5, you can manage the `lang` and `dir` attributes of the `html` tag using `useParams` in your root component. This ensures that the correct attributes are set on the server and client.
466
453
 
467
454
  ```tsx fileName="src/routes/__root.tsx"
468
455
  const RootComponent: ParentComponent = (props) => {
469
- const matches = useMatches();
470
-
471
- // Try to find locale in params of any active match
472
- const locale =
473
- (
474
- matches().find((match) => match.routeId === "/{-$locale}/")
475
- ?.params as Params
476
- )?.locale ?? defaultLocale;
456
+ const params = LocaleRoute.useParams();
457
+ const locale = params()?.locale ?? defaultLocale;
477
458
 
478
459
  return (
479
460
  <html dir={getHTMLTextDir(locale)} lang={locale}>
@@ -186,31 +186,41 @@ export default config;
186
186
 
187
187
  ### Step 5: Create Root Layout
188
188
 
189
- Configure your root layout to support internationalization by using `useMatches` to detect the current locale and setting the `lang` and `dir` attributes on the `html` tag.
189
+ Configure your root layout to support internationalization by using `useParams` to detect the current locale and setting the `lang` and `dir` attributes on the `html` tag.
190
190
 
191
191
  ```tsx fileName="src/routes/__root.tsx"
192
192
  import {
193
193
  createRootRouteWithContext,
194
194
  HeadContent,
195
- Outlet,
196
195
  Scripts,
197
- useMatches,
198
196
  } from "@tanstack/react-router";
199
197
  import { defaultLocale, getHTMLTextDir } from "intlayer";
200
198
  import { type ReactNode } from "react";
201
199
  import { IntlayerProvider } from "react-intlayer";
200
+ import { Route as LocaleRoute } from "./{-$locale}/route";
202
201
 
203
202
  export const Route = createRootRouteWithContext<{}>()({
203
+ head: () => ({
204
+ meta: [
205
+ {
206
+ charSet: "utf-8",
207
+ },
208
+ {
209
+ content: "width=device-width, initial-scale=1",
210
+ name: "viewport",
211
+ },
212
+ {
213
+ title: "TanStack Start Starter",
214
+ },
215
+ ],
216
+ }),
217
+
204
218
  shellComponent: RootDocument,
205
219
  });
206
220
 
207
221
  function RootDocument({ children }: { children: ReactNode }) {
208
- const matches = useMatches();
209
-
210
- // Try to find locale in params of any active match
211
- // This assumes you use the dynamic segment "/{-$locale}" in your route tree
212
- const localeRoute = matches.find((match) => match.routeId === "/{-$locale}");
213
- const locale = localeRoute?.params?.locale ?? defaultLocale;
222
+ const params = LocaleRoute.useParams();
223
+ const locale = params?.locale ?? defaultLocale;
214
224
 
215
225
  return (
216
226
  <html dir={getHTMLTextDir(locale)} lang={locale}>
@@ -218,7 +228,9 @@ function RootDocument({ children }: { children: ReactNode }) {
218
228
  <HeadContent />
219
229
  </head>
220
230
  <body>
221
- <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
231
+ <IntlayerProvider locale={locale}>
232
+ {children}
233
+ </IntlayerProvider>
222
234
  <Scripts />
223
235
  </body>
224
236
  </html>
@@ -561,15 +573,12 @@ export const LocaleSwitcher: FC = () => {
561
573
 
562
574
  ### Step 10: HTML Attributes Management
563
575
 
564
- As seen in Step 5, you can manage the `lang` and `dir` attributes of the `html` tag using `useMatches` in your root component. This ensures that the correct attributes are set on the server and client.
576
+ As seen in Step 5, you can manage the `lang` and `dir` attributes of the `html` tag using `useParams` in your root component. This ensures that the correct attributes are set on the server and client.
565
577
 
566
578
  ```tsx fileName="src/routes/__root.tsx"
567
579
  function RootDocument({ children }: { children: ReactNode }) {
568
- const matches = useMatches();
569
-
570
- // Try to find locale in params of any active match
571
- const localeRoute = matches.find((match) => match.routeId === "/{-$locale}");
572
- const locale = localeRoute?.params?.locale ?? defaultLocale;
580
+ const params = LocaleRoute.useParams();
581
+ const locale = params?.locale ?? defaultLocale;
573
582
 
574
583
  return (
575
584
  <html dir={getHTMLTextDir(locale)} lang={locale}>