@intlayer/docs 8.5.2 → 8.6.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_react_router_v7.md +2 -4
- package/docs/ar/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/ar/intlayer_with_svelte_kit.md +2 -2
- package/docs/ar/intlayer_with_tanstack+solid.md +0 -17
- package/docs/ar/intlayer_with_tanstack.md +0 -8
- package/docs/ar/intlayer_with_vite+lit.md +0 -1
- package/docs/ar/intlayer_with_vite+solid.md +0 -1
- package/docs/ar/intlayer_with_vite+svelte.md +1 -1
- package/docs/bn/intlayer_with_vite+lit.md +0 -1
- package/docs/cs/intlayer_with_vite+lit.md +0 -1
- package/docs/de/intlayer_with_react_router_v7.md +2 -4
- package/docs/de/intlayer_with_react_router_v7_fs_routes.md +1 -2
- package/docs/de/intlayer_with_svelte_kit.md +2 -2
- package/docs/de/intlayer_with_tanstack+solid.md +80 -21
- package/docs/de/intlayer_with_tanstack.md +96 -28
- package/docs/de/intlayer_with_vite+lit.md +0 -1
- package/docs/de/intlayer_with_vite+solid.md +0 -1
- package/docs/de/intlayer_with_vite+svelte.md +1 -1
- package/docs/en/intlayer_with_react_router_v7.md +1 -2
- package/docs/en/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/en/intlayer_with_svelte_kit.md +2 -2
- package/docs/en/intlayer_with_tanstack+solid.md +81 -19
- package/docs/en/intlayer_with_tanstack.md +81 -10
- package/docs/en/intlayer_with_vite+lit.md +0 -1
- package/docs/en/intlayer_with_vite+solid.md +0 -1
- package/docs/en/intlayer_with_vite+svelte.md +5 -6
- package/docs/en-GB/intlayer_with_react_router_v7.md +2 -4
- package/docs/en-GB/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/en-GB/intlayer_with_svelte_kit.md +2 -2
- package/docs/en-GB/intlayer_with_tanstack+solid.md +73 -17
- package/docs/en-GB/intlayer_with_tanstack.md +74 -9
- package/docs/en-GB/intlayer_with_vite+lit.md +0 -1
- package/docs/en-GB/intlayer_with_vite+solid.md +0 -1
- package/docs/en-GB/intlayer_with_vite+svelte.md +1 -1
- package/docs/es/intlayer_with_react_router_v7.md +2 -4
- package/docs/es/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/es/intlayer_with_svelte_kit.md +2 -2
- package/docs/es/intlayer_with_tanstack+solid.md +80 -21
- package/docs/es/intlayer_with_tanstack.md +96 -28
- package/docs/es/intlayer_with_vite+lit.md +0 -1
- package/docs/es/intlayer_with_vite+solid.md +0 -1
- package/docs/es/intlayer_with_vite+svelte.md +1 -1
- package/docs/fr/intlayer_with_react_router_v7.md +2 -4
- package/docs/fr/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/fr/intlayer_with_svelte_kit.md +3 -3
- package/docs/fr/intlayer_with_tanstack+solid.md +80 -21
- package/docs/fr/intlayer_with_tanstack.md +96 -28
- package/docs/fr/intlayer_with_vite+lit.md +0 -1
- package/docs/fr/intlayer_with_vite+solid.md +0 -1
- package/docs/fr/intlayer_with_vite+svelte.md +1 -1
- package/docs/hi/intlayer_with_react_router_v7.md +2 -4
- package/docs/hi/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/hi/intlayer_with_svelte_kit.md +2 -2
- package/docs/hi/intlayer_with_tanstack+solid.md +0 -17
- package/docs/hi/intlayer_with_tanstack.md +0 -8
- package/docs/hi/intlayer_with_vite+lit.md +0 -1
- package/docs/hi/intlayer_with_vite+solid.md +0 -1
- package/docs/hi/intlayer_with_vite+svelte.md +1 -1
- package/docs/id/intlayer_with_react_router_v7.md +2 -4
- package/docs/id/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/id/intlayer_with_svelte_kit.md +2 -2
- package/docs/id/intlayer_with_tanstack+solid.md +0 -17
- package/docs/id/intlayer_with_tanstack.md +0 -8
- package/docs/id/intlayer_with_vite+lit.md +0 -1
- package/docs/id/intlayer_with_vite+solid.md +0 -1
- package/docs/id/intlayer_with_vite+svelte.md +1 -1
- package/docs/it/intlayer_with_react_router_v7.md +2 -4
- package/docs/it/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/it/intlayer_with_svelte_kit.md +3 -3
- package/docs/it/intlayer_with_tanstack+solid.md +78 -19
- package/docs/it/intlayer_with_tanstack.md +96 -30
- package/docs/it/intlayer_with_vite+lit.md +0 -1
- package/docs/it/intlayer_with_vite+solid.md +0 -1
- package/docs/it/intlayer_with_vite+svelte.md +1 -1
- package/docs/ja/intlayer_with_react_router_v7.md +1 -2
- package/docs/ja/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/ja/intlayer_with_tanstack+solid.md +83 -22
- package/docs/ja/intlayer_with_tanstack.md +779 -93
- package/docs/ja/intlayer_with_vite+lit.md +0 -1
- package/docs/ja/intlayer_with_vite+solid.md +0 -1
- package/docs/ja/intlayer_with_vite+svelte.md +1 -1
- package/docs/ko/intlayer_with_react_router_v7.md +2 -4
- package/docs/ko/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/ko/intlayer_with_svelte_kit.md +2 -2
- package/docs/ko/intlayer_with_tanstack+solid.md +81 -22
- package/docs/ko/intlayer_with_tanstack.md +95 -101
- package/docs/ko/intlayer_with_vite+lit.md +0 -1
- package/docs/ko/intlayer_with_vite+solid.md +0 -1
- package/docs/ko/intlayer_with_vite+svelte.md +1 -1
- package/docs/nl/intlayer_with_vite+lit.md +0 -1
- package/docs/pl/intlayer_with_react_router_v7.md +2 -4
- package/docs/pl/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/pl/intlayer_with_svelte_kit.md +2 -2
- package/docs/pl/intlayer_with_tanstack+solid.md +0 -17
- package/docs/pl/intlayer_with_tanstack.md +0 -8
- package/docs/pl/intlayer_with_vite+lit.md +0 -1
- package/docs/pl/intlayer_with_vite+solid.md +0 -1
- package/docs/pl/intlayer_with_vite+svelte.md +1 -1
- package/docs/pt/intlayer_with_react_router_v7.md +1 -2
- package/docs/pt/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/pt/intlayer_with_svelte_kit.md +3 -3
- package/docs/pt/intlayer_with_tanstack+solid.md +78 -19
- package/docs/pt/intlayer_with_tanstack.md +96 -30
- package/docs/pt/intlayer_with_vite+lit.md +0 -1
- package/docs/pt/intlayer_with_vite+solid.md +0 -1
- package/docs/pt/intlayer_with_vite+svelte.md +1 -1
- package/docs/ru/intlayer_with_react_router_v7.md +2 -4
- package/docs/ru/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/ru/intlayer_with_svelte_kit.md +2 -2
- package/docs/ru/intlayer_with_tanstack+solid.md +80 -21
- package/docs/ru/intlayer_with_tanstack.md +99 -33
- package/docs/ru/intlayer_with_vite+lit.md +0 -1
- package/docs/ru/intlayer_with_vite+solid.md +0 -1
- package/docs/ru/intlayer_with_vite+svelte.md +1 -1
- package/docs/tr/intlayer_with_react_router_v7.md +2 -4
- package/docs/tr/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/tr/intlayer_with_svelte_kit.md +2 -2
- package/docs/tr/intlayer_with_tanstack+solid.md +0 -17
- package/docs/tr/intlayer_with_tanstack.md +0 -8
- package/docs/tr/intlayer_with_vite+lit.md +0 -1
- package/docs/tr/intlayer_with_vite+solid.md +0 -1
- package/docs/tr/intlayer_with_vite+svelte.md +1 -1
- package/docs/uk/intlayer_with_react_router_v7.md +1 -2
- package/docs/uk/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/uk/intlayer_with_svelte_kit.md +2 -2
- package/docs/uk/intlayer_with_tanstack+solid.md +0 -17
- package/docs/uk/intlayer_with_tanstack.md +0 -8
- package/docs/uk/intlayer_with_vite+lit.md +0 -1
- package/docs/uk/intlayer_with_vite+solid.md +0 -1
- package/docs/uk/intlayer_with_vite+svelte.md +1 -1
- package/docs/ur/intlayer_with_vite+lit.md +0 -1
- package/docs/vi/intlayer_with_react_router_v7.md +2 -4
- package/docs/vi/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/vi/intlayer_with_svelte_kit.md +2 -2
- package/docs/vi/intlayer_with_tanstack+solid.md +0 -17
- package/docs/vi/intlayer_with_tanstack.md +0 -8
- package/docs/vi/intlayer_with_vite+lit.md +0 -1
- package/docs/vi/intlayer_with_vite+solid.md +0 -1
- package/docs/vi/intlayer_with_vite+svelte.md +1 -1
- package/docs/zh/intlayer_with_react_router_v7.md +2 -4
- package/docs/zh/intlayer_with_react_router_v7_fs_routes.md +2 -4
- package/docs/zh/intlayer_with_svelte_kit.md +2 -2
- package/docs/zh/intlayer_with_tanstack+solid.md +82 -23
- package/docs/zh/intlayer_with_tanstack.md +96 -104
- package/docs/zh/intlayer_with_vite+lit.md +0 -1
- package/docs/zh/intlayer_with_vite+solid.md +0 -1
- package/docs/zh/intlayer_with_vite+svelte.md +1 -1
- package/package.json +8 -8
|
@@ -233,7 +233,7 @@ module.exports = appContent;
|
|
|
233
233
|
<!-- Inhalt als einfachen Inhalt rendern -->
|
|
234
234
|
<h1>{$content.title}</h1>
|
|
235
235
|
<!-- Um den Inhalt editierbar mit dem Editor zu rendern -->
|
|
236
|
-
<h1
|
|
236
|
+
<h1>{@const Title = $content.title}<Title /></h1>
|
|
237
237
|
<!-- Um den Inhalt als String zu rendern -->
|
|
238
238
|
<div aria-label={$content.title.value}></div>
|
|
239
239
|
```
|
|
@@ -184,10 +184,9 @@ Add the intlayer plugin into your configuration:
|
|
|
184
184
|
import { reactRouter } from "@react-router/dev/vite";
|
|
185
185
|
import { defineConfig } from "vite";
|
|
186
186
|
import { intlayer } from "vite-intlayer";
|
|
187
|
-
import tsconfigPaths from "vite-tsconfig-paths";
|
|
188
187
|
|
|
189
188
|
export default defineConfig({
|
|
190
|
-
plugins: [reactRouter(),
|
|
189
|
+
plugins: [reactRouter(), intlayer()],
|
|
191
190
|
});
|
|
192
191
|
```
|
|
193
192
|
|
|
@@ -172,10 +172,9 @@ Add the intlayer plugin into your configuration:
|
|
|
172
172
|
import { reactRouter } from "@react-router/dev/vite";
|
|
173
173
|
import { defineConfig } from "vite";
|
|
174
174
|
import { intlayer } from "vite-intlayer";
|
|
175
|
-
import tsconfigPaths from "vite-tsconfig-paths";
|
|
176
175
|
|
|
177
176
|
export default defineConfig({
|
|
178
|
-
plugins: [reactRouter(),
|
|
177
|
+
plugins: [reactRouter(), intlayer()],
|
|
179
178
|
});
|
|
180
179
|
```
|
|
181
180
|
|
|
@@ -586,13 +585,12 @@ You can also use the `intlayerProxy` to add server-side routing to your applicat
|
|
|
586
585
|
import { reactRouter } from "@react-router/dev/vite";
|
|
587
586
|
import { defineConfig } from "vite";
|
|
588
587
|
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
589
|
-
import tsconfigPaths from "vite-tsconfig-paths";
|
|
590
588
|
|
|
591
589
|
export default defineConfig({
|
|
592
590
|
plugins: [
|
|
593
591
|
intlayerProxy(), // should be placed first
|
|
594
592
|
reactRouter(),
|
|
595
|
-
|
|
593
|
+
|
|
596
594
|
intlayer(),
|
|
597
595
|
],
|
|
598
596
|
});
|
|
@@ -198,7 +198,7 @@ Now you can use the `useIntlayer` function in any Svelte component. It returns a
|
|
|
198
198
|
<!-- Render content as simple content -->
|
|
199
199
|
<h1>{$content.title}</h1>
|
|
200
200
|
<!-- To render the content editable using the editor -->
|
|
201
|
-
<h1
|
|
201
|
+
<h1>{@const Title = $content.title}<Title /></h1>
|
|
202
202
|
<!-- To render the content as a string -->
|
|
203
203
|
<div aria-label={$content.title.value}></div>
|
|
204
204
|
```
|
|
@@ -554,7 +554,7 @@ To be able to visualize the intlayer editor selector, you will have to use the c
|
|
|
554
554
|
<h1>{$content.title}</h1>
|
|
555
555
|
|
|
556
556
|
<!-- Render content as a component (required by the editor) -->
|
|
557
|
-
|
|
557
|
+
{@const Component = $content.component}<Component />
|
|
558
558
|
</div>
|
|
559
559
|
```
|
|
560
560
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-03-25
|
|
3
|
-
updatedAt: 2026-03-
|
|
3
|
+
updatedAt: 2026-03-29
|
|
4
4
|
title: Tanstack Start i18n - How to translate a Tanstack Start app using Solid.js in 2026
|
|
5
5
|
description: Learn how to add internationalization (i18n) to your Tanstack Start application using Intlayer and Solid.js. Follow this comprehensive guide to make your app multilingual with locale-aware routing.
|
|
6
6
|
keywords:
|
|
@@ -12,6 +12,7 @@ keywords:
|
|
|
12
12
|
- i18n
|
|
13
13
|
- TypeScript
|
|
14
14
|
- Locale Routing
|
|
15
|
+
- Sitemap
|
|
15
16
|
slugs:
|
|
16
17
|
- doc
|
|
17
18
|
- environment
|
|
@@ -19,6 +20,9 @@ slugs:
|
|
|
19
20
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-solid-template
|
|
20
21
|
youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
|
|
21
22
|
history:
|
|
23
|
+
- version: 8.6.0
|
|
24
|
+
date: 2026-03-29
|
|
25
|
+
changes: "Add pre-render & sitemap"
|
|
22
26
|
- version: 8.5.1
|
|
23
27
|
date: 2026-03-25
|
|
24
28
|
changes: "Added for Tanstack Start Solid.js"
|
|
@@ -140,16 +144,12 @@ Add the intlayer plugin into your configuration:
|
|
|
140
144
|
import { intlayer } from "vite-intlayer";
|
|
141
145
|
import { defineConfig } from "vite";
|
|
142
146
|
import { devtools } from "@tanstack/devtools-vite";
|
|
143
|
-
import viteTsConfigPaths from "vite-tsconfig-paths";
|
|
144
147
|
import { tanstackStart } from "@tanstack/solid-start/plugin/vite";
|
|
145
148
|
import solidPlugin from "vite-plugin-solid";
|
|
146
149
|
|
|
147
150
|
export default defineConfig({
|
|
148
151
|
plugins: [
|
|
149
152
|
devtools(),
|
|
150
|
-
viteTsConfigPaths({
|
|
151
|
-
projects: ["./tsconfig.json"],
|
|
152
|
-
}),
|
|
153
153
|
tanstackStart({
|
|
154
154
|
router: {
|
|
155
155
|
routeFileIgnorePattern:
|
|
@@ -221,9 +221,6 @@ function RootComponent() {
|
|
|
221
221
|
}
|
|
222
222
|
```
|
|
223
223
|
|
|
224
|
-
> [!NOTE]
|
|
225
|
-
> In Solid, `useMatches` returns a **signal** (reactive accessor). Use `matches()` (with parentheses) to access the current value reactively.
|
|
226
|
-
|
|
227
224
|
### Step 6: Create Locale Layout (Optional)
|
|
228
225
|
|
|
229
226
|
Create a layout that handles the locale prefix and performs validation. This layout will ensure that only valid locales are processed.
|
|
@@ -415,7 +412,6 @@ function RouteComponent() {
|
|
|
415
412
|
}
|
|
416
413
|
```
|
|
417
414
|
|
|
418
|
-
> [!NOTE]
|
|
419
415
|
> In Solid, `useIntlayer` returns an **accessor** function (e.g., `content()`). You must call this function to access the reactive content.
|
|
420
416
|
>
|
|
421
417
|
> To Learn more about the `useIntlayer` hook, refer to the [documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/packages/solid-intlayer/useIntlayer.md).
|
|
@@ -460,7 +456,6 @@ export const LocaleSwitcher = () => {
|
|
|
460
456
|
export default LocaleSwitcher;
|
|
461
457
|
```
|
|
462
458
|
|
|
463
|
-
> [!NOTE]
|
|
464
459
|
> In Solid, `locale` from `useLocale` is a **signal accessor**. Use `locale()` (with parentheses) to read its current value reactively.
|
|
465
460
|
>
|
|
466
461
|
> To Learn more about the `useLocale` hook, refer to the [documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/packages/solid-intlayer/useLocale.md).
|
|
@@ -502,15 +497,11 @@ import solid from "vite-plugin-solid";
|
|
|
502
497
|
import { nitro } from "nitro/vite";
|
|
503
498
|
import { defineConfig } from "vite";
|
|
504
499
|
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
505
|
-
import viteTsConfigPaths from "vite-tsconfig-paths";
|
|
506
500
|
|
|
507
501
|
export default defineConfig({
|
|
508
502
|
plugins: [
|
|
509
503
|
intlayerProxy(), // The proxy should be placed before server if you use Nitro
|
|
510
504
|
nitro(),
|
|
511
|
-
viteTsConfigPaths({
|
|
512
|
-
projects: ["./tsconfig.json"],
|
|
513
|
-
}),
|
|
514
505
|
intlayer(),
|
|
515
506
|
tanstackStart({
|
|
516
507
|
router: {
|
|
@@ -803,16 +794,12 @@ Update your `vite.config.ts` to include the `intlayerCompiler` plugin:
|
|
|
803
794
|
import { intlayer, intlayerCompiler } from "vite-intlayer";
|
|
804
795
|
import { defineConfig } from "vite";
|
|
805
796
|
import { devtools } from "@tanstack/devtools-vite";
|
|
806
|
-
import viteTsConfigPaths from "vite-tsconfig-paths";
|
|
807
797
|
import { tanstackStart } from "@tanstack/solid-start/plugin/vite";
|
|
808
798
|
import solidPlugin from "vite-plugin-solid";
|
|
809
799
|
|
|
810
800
|
export default defineConfig({
|
|
811
801
|
plugins: [
|
|
812
802
|
devtools(),
|
|
813
|
-
viteTsConfigPaths({
|
|
814
|
-
projects: ["./tsconfig.json"],
|
|
815
|
-
}),
|
|
816
803
|
tanstackStart({
|
|
817
804
|
router: {
|
|
818
805
|
routeFileIgnorePattern:
|
|
@@ -847,7 +834,82 @@ bun run build # Or bun run dev
|
|
|
847
834
|
|
|
848
835
|
---
|
|
849
836
|
|
|
850
|
-
### Step 16:
|
|
837
|
+
### Step 16: Pre-render & Generate Sitemap (Optional)
|
|
838
|
+
|
|
839
|
+
Intlayer comes with a built-in sitemap generator to help you create a sitemap for your application easily. It handles localized routes and adds the necessary metadata for search engines.
|
|
840
|
+
|
|
841
|
+
> The Intlayer generated sitemap supports the `xhtml:link` namespace (Hreflang XML Extensions). Unlike the default sitemap generators that only list raw URLs, Intlayer automatically creates the required bidirectional links between all language versions of a page (e.g., `/about`, `/about?lang=fr`, and `/about?lang=es`). This ensures search engines correctly index and serve the right language version to the right audience.
|
|
842
|
+
|
|
843
|
+
To use it, you first need to configure your `vite.config.ts` to enable pre-rendering for your localized routes and disable the default TanStack Start sitemap generation.
|
|
844
|
+
|
|
845
|
+
```typescript fileName="vite.config.ts"
|
|
846
|
+
import { localeMap, localeFlatMap } from "intlayer";
|
|
847
|
+
// ... other imports
|
|
848
|
+
|
|
849
|
+
export const pathList = ["", "/about", "/404"];
|
|
850
|
+
|
|
851
|
+
const localizedPages = localeFlatMap(({ urlPrefix }) =>
|
|
852
|
+
pathList.map((path) => ({
|
|
853
|
+
path: `${urlPrefix}${path}`,
|
|
854
|
+
prerender: {
|
|
855
|
+
enabled: true,
|
|
856
|
+
},
|
|
857
|
+
}))
|
|
858
|
+
);
|
|
859
|
+
|
|
860
|
+
export default defineConfig({
|
|
861
|
+
plugins: [
|
|
862
|
+
// ... other plugins
|
|
863
|
+
tanstackStart({
|
|
864
|
+
// ... other config
|
|
865
|
+
sitemap: {
|
|
866
|
+
enabled: false,
|
|
867
|
+
},
|
|
868
|
+
prerender: {
|
|
869
|
+
enabled: true,
|
|
870
|
+
crawlLinks: false,
|
|
871
|
+
concurrency: 10,
|
|
872
|
+
},
|
|
873
|
+
pages: localizedPages,
|
|
874
|
+
}),
|
|
875
|
+
],
|
|
876
|
+
});
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
Then, create a `src/routes/sitemap[.]xml.ts` route that uses the `generateSitemap` function:
|
|
880
|
+
|
|
881
|
+
```typescript fileName="src/routes/sitemap[.]xml.ts"
|
|
882
|
+
import { createFileRoute } from "@tanstack/solid-router";
|
|
883
|
+
import { generateSitemap } from "intlayer";
|
|
884
|
+
|
|
885
|
+
const SITE_URL = (
|
|
886
|
+
import.meta.env.VITE_SITE_URL ?? "http://localhost:3000"
|
|
887
|
+
).replace(/\/$/, "");
|
|
888
|
+
|
|
889
|
+
export const Route = createFileRoute("/sitemap.xml")({
|
|
890
|
+
server: {
|
|
891
|
+
handlers: {
|
|
892
|
+
GET: async () => {
|
|
893
|
+
const sitemap = generateSitemap(
|
|
894
|
+
[
|
|
895
|
+
{ path: "/", changefreq: "daily", priority: 1.0 },
|
|
896
|
+
{ path: "/about", changefreq: "monthly", priority: 0.8 },
|
|
897
|
+
],
|
|
898
|
+
{ siteUrl: SITE_URL }
|
|
899
|
+
);
|
|
900
|
+
|
|
901
|
+
return new Response(sitemap, {
|
|
902
|
+
headers: { "Content-Type": "application/xml" },
|
|
903
|
+
});
|
|
904
|
+
},
|
|
905
|
+
},
|
|
906
|
+
},
|
|
907
|
+
});
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
---
|
|
911
|
+
|
|
912
|
+
### Step 17: Configure TypeScript (Optional)
|
|
851
913
|
|
|
852
914
|
Intlayer uses module augmentation to get benefits of TypeScript and make your codebase stronger.
|
|
853
915
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
|
-
updatedAt:
|
|
3
|
+
updatedAt: 2026-03-29
|
|
4
4
|
title: Tanstack Start i18n - How to translate an Tanstack Start app in 2026
|
|
5
5
|
description: Learn how to add internationalization (i18n) to your Tanstack Start application using Intlayer. Follow this comprehensive guide to make your app multilingual with locale-aware routing.
|
|
6
6
|
keywords:
|
|
@@ -12,6 +12,7 @@ keywords:
|
|
|
12
12
|
- i18n
|
|
13
13
|
- TypeScript
|
|
14
14
|
- Locale Routing
|
|
15
|
+
- Sitemap
|
|
15
16
|
slugs:
|
|
16
17
|
- doc
|
|
17
18
|
- environment
|
|
@@ -19,6 +20,9 @@ slugs:
|
|
|
19
20
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
|
|
20
21
|
youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
|
|
21
22
|
history:
|
|
23
|
+
- version: 8.6.0
|
|
24
|
+
date: 2026-03-29
|
|
25
|
+
changes: "Add pre-render & sitemap"
|
|
22
26
|
- version: 7.5.9
|
|
23
27
|
date: 2025-12-30
|
|
24
28
|
changes: "Add init command"
|
|
@@ -160,14 +164,10 @@ import viteReact from "@vitejs/plugin-react";
|
|
|
160
164
|
import { nitro } from "nitro/vite";
|
|
161
165
|
import { defineConfig } from "vite";
|
|
162
166
|
import { intlayer } from "vite-intlayer";
|
|
163
|
-
import viteTsConfigPaths from "vite-tsconfig-paths";
|
|
164
167
|
|
|
165
168
|
const config = defineConfig({
|
|
166
169
|
plugins: [
|
|
167
170
|
nitro(),
|
|
168
|
-
viteTsConfigPaths({
|
|
169
|
-
projects: ["./tsconfig.json"],
|
|
170
|
-
}),
|
|
171
171
|
intlayer(),
|
|
172
172
|
tanstackStart({
|
|
173
173
|
router: {
|
|
@@ -593,15 +593,11 @@ import viteReact from "@vitejs/plugin-react";
|
|
|
593
593
|
import { nitro } from "nitro/vite";
|
|
594
594
|
import { defineConfig } from "vite";
|
|
595
595
|
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
596
|
-
import viteTsConfigPaths from "vite-tsconfig-paths";
|
|
597
596
|
|
|
598
597
|
export default defineConfig({
|
|
599
598
|
plugins: [
|
|
600
599
|
intlayerProxy(), // The proxy should be placed before server if you use Nitro
|
|
601
600
|
nitro(),
|
|
602
|
-
viteTsConfigPaths({
|
|
603
|
-
projects: ["./tsconfig.json"],
|
|
604
|
-
}),
|
|
605
601
|
intlayer(),
|
|
606
602
|
tanstackStart({
|
|
607
603
|
router: {
|
|
@@ -923,7 +919,82 @@ bun run build # Or bun run dev
|
|
|
923
919
|
|
|
924
920
|
---
|
|
925
921
|
|
|
926
|
-
### Step 16:
|
|
922
|
+
### Step 16: Pre-render & Generate Sitemap (Optional)
|
|
923
|
+
|
|
924
|
+
Intlayer comes with a built-in sitemap generator to help you create a sitemap for your application easily. It handles localized routes and adds the necessary metadata for search engines.
|
|
925
|
+
|
|
926
|
+
> The Intlayer generated sitemap supports the `xhtml:link` namespace (Hreflang XML Extensions). Unlike the default sitemap generators that only list raw URLs, Intlayer automatically creates the required bidirectional links between all language versions of a page (e.g., `/about`, `/about?lang=fr`, and `/about?lang=es`). This ensures search engines correctly index and serve the right language version to the right audience.
|
|
927
|
+
|
|
928
|
+
To use it, you first need to configure your `vite.config.ts` to enable pre-rendering for your localized routes and disable the default TanStack Start sitemap generation.
|
|
929
|
+
|
|
930
|
+
```typescript fileName="vite.config.ts"
|
|
931
|
+
import { localeFlatMap } from "intlayer";
|
|
932
|
+
// ... other imports
|
|
933
|
+
|
|
934
|
+
export const pathList = ["", "/about", "/404"];
|
|
935
|
+
|
|
936
|
+
const localizedPages = localeFlatMap(({ urlPrefix }) =>
|
|
937
|
+
pathList.map((path) => ({
|
|
938
|
+
path: `${urlPrefix}${path}`,
|
|
939
|
+
prerender: {
|
|
940
|
+
enabled: true,
|
|
941
|
+
},
|
|
942
|
+
}))
|
|
943
|
+
);
|
|
944
|
+
|
|
945
|
+
export default defineConfig({
|
|
946
|
+
plugins: [
|
|
947
|
+
// ... other plugins
|
|
948
|
+
tanstackStart({
|
|
949
|
+
// ... other config
|
|
950
|
+
sitemap: {
|
|
951
|
+
enabled: false,
|
|
952
|
+
},
|
|
953
|
+
prerender: {
|
|
954
|
+
enabled: true,
|
|
955
|
+
crawlLinks: false,
|
|
956
|
+
concurrency: 10,
|
|
957
|
+
},
|
|
958
|
+
pages: localizedPages,
|
|
959
|
+
}),
|
|
960
|
+
],
|
|
961
|
+
});
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
Then, create a `src/routes/sitemap[.]xml.ts` route that uses the `generateSitemap` function:
|
|
965
|
+
|
|
966
|
+
```typescript fileName="src/routes/sitemap[.]xml.ts"
|
|
967
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
968
|
+
import { generateSitemap } from "intlayer";
|
|
969
|
+
|
|
970
|
+
const SITE_URL = (
|
|
971
|
+
import.meta.env.VITE_SITE_URL ?? "http://localhost:3000"
|
|
972
|
+
).replace(/\/$/, "");
|
|
973
|
+
|
|
974
|
+
export const Route = createFileRoute("/sitemap.xml")({
|
|
975
|
+
server: {
|
|
976
|
+
handlers: {
|
|
977
|
+
GET: async () => {
|
|
978
|
+
const sitemap = generateSitemap(
|
|
979
|
+
[
|
|
980
|
+
{ path: "/", changefreq: "daily", priority: 1.0 },
|
|
981
|
+
{ path: "/about", changefreq: "monthly", priority: 0.8 },
|
|
982
|
+
],
|
|
983
|
+
{ siteUrl: SITE_URL }
|
|
984
|
+
);
|
|
985
|
+
|
|
986
|
+
return new Response(sitemap, {
|
|
987
|
+
headers: { "Content-Type": "application/xml" },
|
|
988
|
+
});
|
|
989
|
+
},
|
|
990
|
+
},
|
|
991
|
+
},
|
|
992
|
+
});
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
---
|
|
996
|
+
|
|
997
|
+
### Step 17: Configure TypeScript (Optional)
|
|
927
998
|
|
|
928
999
|
Intlayer uses module augmentation to get benefits of TypeScript and make your codebase stronger.
|
|
929
1000
|
|
|
@@ -438,7 +438,6 @@ const App: Component = () => (
|
|
|
438
438
|
export default App;
|
|
439
439
|
```
|
|
440
440
|
|
|
441
|
-
> [!NOTE]
|
|
442
441
|
> In Solid, `useIntlayer` returns an **accessor** function (e.g., `content()`). You must call this function to access the reactive content.
|
|
443
442
|
|
|
444
443
|
> If you want to use your content in a `string` attribute, such as `alt`, `title`, `href`, `aria-label`, etc., you must call the value of the function, like:
|
|
@@ -230,7 +230,7 @@ module.exports = appContent;
|
|
|
230
230
|
<!-- Render content as simple content -->
|
|
231
231
|
<h1>{$content.title}</h1>
|
|
232
232
|
<!-- To render the content editable using the editor -->
|
|
233
|
-
<h1
|
|
233
|
+
<h1>{@const Title = $content.title}<Title /></h1>
|
|
234
234
|
<!-- To render the content as a string -->
|
|
235
235
|
<div aria-label={$content.title.value}></div>
|
|
236
236
|
```
|
|
@@ -270,7 +270,7 @@ const changeLocale = (event: Event) => {
|
|
|
270
270
|
|
|
271
271
|
Intlayer supports rendering Markdown and HTML content in Svelte.
|
|
272
272
|
|
|
273
|
-
By default, Intlayer treats Markdown and HTML as interactive components or strings. To render them in Svelte, you can use the
|
|
273
|
+
By default, Intlayer treats Markdown and HTML as interactive components or strings. To render them in Svelte, you can use the `{@const Component = ...}<Component />` for components or `{@html ...}` for plain strings.
|
|
274
274
|
|
|
275
275
|
```svelte fileName="src/App.svelte"
|
|
276
276
|
<script>
|
|
@@ -280,14 +280,13 @@ By default, Intlayer treats Markdown and HTML as interactive components or strin
|
|
|
280
280
|
</script>
|
|
281
281
|
|
|
282
282
|
<!-- Render Markdown as a Component -->
|
|
283
|
-
|
|
283
|
+
{@const MyMarkdownContent = $content.myMarkdownContent}<MyMarkdownContent />
|
|
284
284
|
|
|
285
285
|
<!-- Render HTML Content -->
|
|
286
286
|
{@html $content.myHtmlContent.toString()}
|
|
287
287
|
|
|
288
288
|
<!-- Render with custom component overrides -->
|
|
289
|
-
|
|
290
|
-
this={$content.myMarkdownContent.use({
|
|
289
|
+
{@const MyMarkdownContent = $content.myMarkdownContent.use({
|
|
291
290
|
h1: (props) => {
|
|
292
291
|
const h1 = document.createElement('h1');
|
|
293
292
|
h1.style.color = 'red';
|
|
@@ -300,7 +299,7 @@ By default, Intlayer treats Markdown and HTML as interactive components or strin
|
|
|
300
299
|
return div;
|
|
301
300
|
}
|
|
302
301
|
})}
|
|
303
|
-
/>
|
|
302
|
+
<MyMarkdownContent />
|
|
304
303
|
```
|
|
305
304
|
|
|
306
305
|
> [!TIP]
|
|
@@ -174,10 +174,9 @@ Add the intlayer plugin into your configuration:
|
|
|
174
174
|
import { reactRouter } from "@react-router/dev/vite";
|
|
175
175
|
import { defineConfig } from "vite";
|
|
176
176
|
import { intlayer } from "vite-intlayer";
|
|
177
|
-
import tsconfigPaths from "vite-tsconfig-paths";
|
|
178
177
|
|
|
179
178
|
export default defineConfig({
|
|
180
|
-
plugins: [reactRouter(),
|
|
179
|
+
plugins: [reactRouter(), intlayer()],
|
|
181
180
|
});
|
|
182
181
|
```
|
|
183
182
|
|
|
@@ -512,13 +511,12 @@ You can also use the `intlayerProxy` to add server-side routing to your applicat
|
|
|
512
511
|
import { reactRouter } from "@react-router/dev/vite";
|
|
513
512
|
import { defineConfig } from "vite";
|
|
514
513
|
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
515
|
-
import tsconfigPaths from "vite-tsconfig-paths";
|
|
516
514
|
|
|
517
515
|
export default defineConfig({
|
|
518
516
|
plugins: [
|
|
519
517
|
intlayerProxy(), // should be placed first
|
|
520
518
|
reactRouter(),
|
|
521
|
-
|
|
519
|
+
|
|
522
520
|
intlayer(),
|
|
523
521
|
],
|
|
524
522
|
});
|
|
@@ -173,10 +173,9 @@ Add the intlayer plugin into your configuration:
|
|
|
173
173
|
import { reactRouter } from "@react-router/dev/vite";
|
|
174
174
|
import { defineConfig } from "vite";
|
|
175
175
|
import { intlayer } from "vite-intlayer";
|
|
176
|
-
import tsconfigPaths from "vite-tsconfig-paths";
|
|
177
176
|
|
|
178
177
|
export default defineConfig({
|
|
179
|
-
plugins: [reactRouter(),
|
|
178
|
+
plugins: [reactRouter(), intlayer()],
|
|
180
179
|
});
|
|
181
180
|
```
|
|
182
181
|
|
|
@@ -457,13 +456,12 @@ You can also use the `intlayerProxy` to add server-side routing to your applicat
|
|
|
457
456
|
import { reactRouter } from "@react-router/dev/vite";
|
|
458
457
|
import { defineConfig } from "vite";
|
|
459
458
|
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
460
|
-
import tsconfigPaths from "vite-tsconfig-paths";
|
|
461
459
|
|
|
462
460
|
export default defineConfig({
|
|
463
461
|
plugins: [
|
|
464
462
|
intlayerProxy(), // should be placed first
|
|
465
463
|
reactRouter(),
|
|
466
|
-
|
|
464
|
+
|
|
467
465
|
intlayer(),
|
|
468
466
|
],
|
|
469
467
|
});
|
|
@@ -370,7 +370,7 @@ prefix to access its reactive value (e.g., `$content.title`).
|
|
|
370
370
|
<!-- Render content as simple content -->
|
|
371
371
|
<h1>{$content.title}</h1>
|
|
372
372
|
<!-- To render the content editable using the editor -->
|
|
373
|
-
<h1
|
|
373
|
+
<h1>{@const Title = $content.title}<Title /></h1>
|
|
374
374
|
<!-- To render the content as a string -->
|
|
375
375
|
<div aria-label={$content.title.value}></div>
|
|
376
376
|
```
|
|
@@ -728,7 +728,7 @@ To be able to visualise the intlayer editor selector, you will have to use the c
|
|
|
728
728
|
<h1>{$content.title}</h1>
|
|
729
729
|
|
|
730
730
|
<!-- Render content as a component (required by the editor) -->
|
|
731
|
-
|
|
731
|
+
{@const Component = $content.component}<Component />
|
|
732
732
|
</div>
|
|
733
733
|
```
|
|
734
734
|
|
|
@@ -140,16 +140,12 @@ Add the intlayer plugin in your configuration:
|
|
|
140
140
|
import { intlayer } from "vite-intlayer";
|
|
141
141
|
import { defineConfig } from "vite";
|
|
142
142
|
import { devtools } from "@tanstack/devtools-vite";
|
|
143
|
-
import viteTsConfigPaths from "vite-tsconfig-paths";
|
|
144
143
|
import { tanstackStart } from "@tanstack/solid-start/plugin/vite";
|
|
145
144
|
import solidPlugin from "vite-plugin-solid";
|
|
146
145
|
|
|
147
146
|
export default defineConfig({
|
|
148
147
|
plugins: [
|
|
149
148
|
devtools(),
|
|
150
|
-
viteTsConfigPaths({
|
|
151
|
-
projects: ["./tsconfig.json"],
|
|
152
|
-
}),
|
|
153
149
|
tanstackStart({
|
|
154
150
|
router: {
|
|
155
151
|
routeFileIgnorePattern:
|
|
@@ -221,9 +217,6 @@ function RootComponent() {
|
|
|
221
217
|
}
|
|
222
218
|
```
|
|
223
219
|
|
|
224
|
-
> [!NOTE]
|
|
225
|
-
> in Solid files, `useMatches` returns a **signal** (reactive accessor). Use `matches()` (with parentheses) to reactively access the current value.
|
|
226
|
-
|
|
227
220
|
### Step 6: Create the Locale Layout (Optional)
|
|
228
221
|
|
|
229
222
|
Create a layout that handles the locale prefix and performs validation. This layout will ensure only valid locales are processed.
|
|
@@ -416,7 +409,6 @@ function RouteComponent() {
|
|
|
416
409
|
}
|
|
417
410
|
```
|
|
418
411
|
|
|
419
|
-
> [!NOTE]
|
|
420
412
|
> in Solid, `useIntlayer` returns an **accessor** function (ex: `content()`). You must call this function to access the reactive content.
|
|
421
413
|
>
|
|
422
414
|
> To learn more about the `useIntlayer` hook, refer to the [documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/packages/solid-intlayer/useIntlayer.md).
|
|
@@ -461,7 +453,6 @@ export const LocaleSwitcher = () => {
|
|
|
461
453
|
export default LocaleSwitcher;
|
|
462
454
|
```
|
|
463
455
|
|
|
464
|
-
> [!NOTE]
|
|
465
456
|
> in Solid files, `locale` from `useLocale` is a **signal accessor**. Use `locale()` (with parentheses) to reactively read its current value.
|
|
466
457
|
>
|
|
467
458
|
> To learn more about the `useLocale` hook, refer to the [documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/packages/solid-intlayer/useLocale.md).
|
|
@@ -503,15 +494,11 @@ import solid from "vite-plugin-solid";
|
|
|
503
494
|
import { nitro } from "nitro/vite";
|
|
504
495
|
import { defineConfig } from "vite";
|
|
505
496
|
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
506
|
-
import viteTsConfigPaths from "vite-tsconfig-paths";
|
|
507
497
|
|
|
508
498
|
export default defineConfig({
|
|
509
499
|
plugins: [
|
|
510
500
|
intlayerProxy(), // The Proxy should be placed before the server if you use Nitro
|
|
511
501
|
nitro(),
|
|
512
|
-
viteTsConfigPaths({
|
|
513
|
-
projects: ["./tsconfig.json"],
|
|
514
|
-
}),
|
|
515
502
|
intlayer(),
|
|
516
503
|
tanstackStart({
|
|
517
504
|
router: {
|
|
@@ -804,16 +791,12 @@ Update your `vite.config.ts` to include the `intlayerCompiler` plugin:
|
|
|
804
791
|
import { intlayer, intlayerCompiler } from "vite-intlayer";
|
|
805
792
|
import { defineConfig } from "vite";
|
|
806
793
|
import { devtools } from "@tanstack/devtools-vite";
|
|
807
|
-
import viteTsConfigPaths from "vite-tsconfig-paths";
|
|
808
794
|
import { tanstackStart } from "@tanstack/solid-start/plugin/vite";
|
|
809
795
|
import solidPlugin from "vite-plugin-solid";
|
|
810
796
|
|
|
811
797
|
export default defineConfig({
|
|
812
798
|
plugins: [
|
|
813
799
|
devtools(),
|
|
814
|
-
viteTsConfigPaths({
|
|
815
|
-
projects: ["./tsconfig.json"],
|
|
816
|
-
}),
|
|
817
800
|
tanstackStart({
|
|
818
801
|
router: {
|
|
819
802
|
routeFileIgnorePattern:
|
|
@@ -848,6 +831,79 @@ bun run build # Or bun run dev
|
|
|
848
831
|
|
|
849
832
|
---
|
|
850
833
|
|
|
834
|
+
### Step 16: Generate Sitemap (Optional)
|
|
835
|
+
|
|
836
|
+
Intlayer comes with a built-in sitemap generator to help you create a sitemap for your application easily. It handles localised routes and adds the necessary metadata for search engines.
|
|
837
|
+
|
|
838
|
+
To use it, you first need to configure your `vite.config.ts` to enable pre-rendering for your localised routes and disable the default TanStack Start sitemap generation.
|
|
839
|
+
|
|
840
|
+
```typescript fileName="vite.config.ts"
|
|
841
|
+
import { localeMap, localeFlatMap } from "intlayer";
|
|
842
|
+
// ... other imports
|
|
843
|
+
|
|
844
|
+
export const pathList = ["", "/about", "/404"];
|
|
845
|
+
|
|
846
|
+
const localizedPages = localeFlatMap(({ urlPrefix }) =>
|
|
847
|
+
pathList.map((path) => ({
|
|
848
|
+
path: `${urlPrefix}${path}`,
|
|
849
|
+
prerender: {
|
|
850
|
+
enabled: true,
|
|
851
|
+
},
|
|
852
|
+
}))
|
|
853
|
+
);
|
|
854
|
+
|
|
855
|
+
export default defineConfig({
|
|
856
|
+
plugins: [
|
|
857
|
+
// ... other plugins
|
|
858
|
+
tanstackStart({
|
|
859
|
+
// ... other config
|
|
860
|
+
sitemap: {
|
|
861
|
+
enabled: false,
|
|
862
|
+
},
|
|
863
|
+
prerender: {
|
|
864
|
+
enabled: true,
|
|
865
|
+
crawlLinks: false,
|
|
866
|
+
concurrency: 10,
|
|
867
|
+
},
|
|
868
|
+
pages: localizedPages,
|
|
869
|
+
}),
|
|
870
|
+
],
|
|
871
|
+
});
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
Then, create a `src/routes/sitemap[.]xml.ts` route that uses the `generateSitemap` function:
|
|
875
|
+
|
|
876
|
+
```typescript fileName="src/routes/sitemap[.]xml.ts"
|
|
877
|
+
import { createFileRoute } from "@tanstack/solid-router";
|
|
878
|
+
import { generateSitemap } from "intlayer";
|
|
879
|
+
|
|
880
|
+
const SITE_URL = (
|
|
881
|
+
import.meta.env.VITE_SITE_URL ?? "http://localhost:3000"
|
|
882
|
+
).replace(/\/$/, "");
|
|
883
|
+
|
|
884
|
+
export const Route = createFileRoute("/sitemap.xml")({
|
|
885
|
+
server: {
|
|
886
|
+
handlers: {
|
|
887
|
+
GET: async () => {
|
|
888
|
+
const sitemap = generateSitemap(
|
|
889
|
+
[
|
|
890
|
+
{ path: "/", changefreq: "daily", priority: 1.0 },
|
|
891
|
+
{ path: "/about", changefreq: "monthly", priority: 0.8 },
|
|
892
|
+
],
|
|
893
|
+
{ siteUrl: SITE_URL }
|
|
894
|
+
);
|
|
895
|
+
|
|
896
|
+
return new Response(sitemap, {
|
|
897
|
+
headers: { "Content-Type": "application/xml" },
|
|
898
|
+
});
|
|
899
|
+
},
|
|
900
|
+
},
|
|
901
|
+
},
|
|
902
|
+
});
|
|
903
|
+
```
|
|
904
|
+
|
|
905
|
+
---
|
|
906
|
+
|
|
851
907
|
### Step 17: Configure TypeScript (Optional)
|
|
852
908
|
|
|
853
909
|
Intlayer uses module augmentation to get the benefits of TypeScript and make your codebase stronger.
|