@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.
- package/dist/cjs/doc.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +60 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/doc.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +60 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/doc.d.ts.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +3 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/cli/index.md +54 -42
- package/docs/ar/cli/init.md +32 -20
- package/docs/ar/cli/standalone.md +91 -0
- package/docs/ar/configuration.md +39 -7
- package/docs/ar/custom_domains.md +250 -0
- package/docs/ar/intlayer_with_tanstack+solid.md +14 -33
- package/docs/ar/intlayer_with_tanstack.md +25 -16
- package/docs/ar/intlayer_with_vanilla.md +506 -0
- package/docs/bn/cli/index.md +195 -0
- package/docs/bn/cli/init.md +96 -0
- package/docs/bn/cli/standalone.md +91 -0
- package/docs/bn/configuration.md +46 -14
- package/docs/bn/custom_domains.md +250 -0
- package/docs/bn/intlayer_with_vanilla.md +506 -0
- package/docs/cs/cli/index.md +195 -0
- package/docs/cs/cli/init.md +96 -0
- package/docs/cs/cli/standalone.md +91 -0
- package/docs/cs/configuration.md +46 -7
- package/docs/cs/custom_domains.md +250 -0
- package/docs/cs/intlayer_with_vanilla.md +506 -0
- package/docs/de/cli/index.md +53 -41
- package/docs/de/cli/standalone.md +91 -0
- package/docs/de/configuration.md +46 -7
- package/docs/de/custom_domains.md +250 -0
- package/docs/de/intlayer_with_tanstack+solid.md +14 -33
- package/docs/de/intlayer_with_tanstack.md +25 -16
- package/docs/de/intlayer_with_vanilla.md +506 -0
- package/docs/en/bundle_optimization.md +288 -23
- package/docs/en/cli/index.md +6 -1
- package/docs/en/cli/init.md +13 -1
- package/docs/en/cli/standalone.md +91 -0
- package/docs/en/configuration.md +46 -7
- package/docs/en/custom_domains.md +245 -0
- package/docs/en/intlayer_with_tanstack+solid.md +14 -33
- package/docs/en/intlayer_with_tanstack.md +25 -16
- package/docs/en/intlayer_with_vanilla.md +506 -0
- package/docs/en-GB/cli/index.md +56 -44
- package/docs/en-GB/cli/init.md +28 -21
- package/docs/en-GB/cli/standalone.md +91 -0
- package/docs/en-GB/configuration.md +53 -14
- package/docs/en-GB/custom_domains.md +250 -0
- package/docs/en-GB/intlayer_with_tanstack+solid.md +14 -33
- package/docs/en-GB/intlayer_with_tanstack.md +25 -16
- package/docs/en-GB/intlayer_with_vanilla.md +506 -0
- package/docs/es/cli/index.md +65 -53
- package/docs/es/cli/init.md +33 -21
- package/docs/es/cli/standalone.md +91 -0
- package/docs/es/configuration.md +39 -1
- package/docs/es/custom_domains.md +250 -0
- package/docs/es/intlayer_with_tanstack+solid.md +14 -33
- package/docs/es/intlayer_with_tanstack.md +25 -16
- package/docs/es/intlayer_with_vanilla.md +506 -0
- package/docs/fr/cli/index.md +43 -31
- package/docs/fr/cli/init.md +37 -25
- package/docs/fr/cli/standalone.md +91 -0
- package/docs/fr/configuration.md +46 -7
- package/docs/fr/custom_domains.md +250 -0
- package/docs/fr/intlayer_with_tanstack+solid.md +14 -33
- package/docs/fr/intlayer_with_tanstack.md +25 -16
- package/docs/fr/intlayer_with_vanilla.md +506 -0
- package/docs/hi/cli/index.md +71 -59
- package/docs/hi/cli/init.md +37 -33
- package/docs/hi/cli/standalone.md +91 -0
- package/docs/hi/configuration.md +39 -7
- package/docs/hi/custom_domains.md +250 -0
- package/docs/hi/intlayer_with_tanstack+solid.md +14 -33
- package/docs/hi/intlayer_with_tanstack.md +25 -16
- package/docs/hi/intlayer_with_vanilla.md +506 -0
- package/docs/id/cli/index.md +59 -47
- package/docs/id/cli/init.md +32 -25
- package/docs/id/cli/standalone.md +91 -0
- package/docs/id/configuration.md +46 -7
- package/docs/id/custom_domains.md +250 -0
- package/docs/id/intlayer_with_tanstack+solid.md +14 -33
- package/docs/id/intlayer_with_tanstack.md +25 -16
- package/docs/id/intlayer_with_vanilla.md +506 -0
- package/docs/it/cli/index.md +58 -41
- package/docs/it/cli/init.md +37 -38
- package/docs/it/cli/standalone.md +91 -0
- package/docs/it/configuration.md +46 -7
- package/docs/it/custom_domains.md +250 -0
- package/docs/it/intlayer_with_tanstack+solid.md +14 -33
- package/docs/it/intlayer_with_tanstack.md +25 -16
- package/docs/it/intlayer_with_vanilla.md +506 -0
- package/docs/ja/cli/index.md +59 -47
- package/docs/ja/cli/init.md +36 -24
- package/docs/ja/cli/standalone.md +91 -0
- package/docs/ja/configuration.md +46 -7
- package/docs/ja/custom_domains.md +250 -0
- package/docs/ja/intlayer_with_tanstack+solid.md +14 -33
- package/docs/ja/intlayer_with_tanstack.md +25 -16
- package/docs/ja/intlayer_with_vanilla.md +506 -0
- package/docs/ko/cli/index.md +58 -46
- package/docs/ko/cli/init.md +39 -35
- package/docs/ko/cli/standalone.md +91 -0
- package/docs/ko/configuration.md +47 -8
- package/docs/ko/custom_domains.md +250 -0
- package/docs/ko/intlayer_with_tanstack+solid.md +14 -33
- package/docs/ko/intlayer_with_tanstack.md +25 -16
- package/docs/ko/intlayer_with_vanilla.md +506 -0
- package/docs/nl/cli/index.md +195 -0
- package/docs/nl/cli/init.md +96 -0
- package/docs/nl/cli/standalone.md +91 -0
- package/docs/nl/configuration.md +46 -7
- package/docs/nl/custom_domains.md +250 -0
- package/docs/nl/intlayer_with_vanilla.md +506 -0
- package/docs/pl/cli/index.md +56 -44
- package/docs/pl/cli/init.md +36 -32
- package/docs/pl/cli/standalone.md +91 -0
- package/docs/pl/configuration.md +46 -7
- package/docs/pl/custom_domains.md +250 -0
- package/docs/pl/intlayer_with_tanstack+solid.md +14 -33
- package/docs/pl/intlayer_with_tanstack.md +25 -16
- package/docs/pl/intlayer_with_vanilla.md +506 -0
- package/docs/pt/cli/index.md +64 -52
- package/docs/pt/cli/init.md +35 -31
- package/docs/pt/cli/standalone.md +91 -0
- package/docs/pt/configuration.md +46 -7
- package/docs/pt/custom_domains.md +250 -0
- package/docs/pt/intlayer_with_tanstack+solid.md +14 -33
- package/docs/pt/intlayer_with_tanstack.md +25 -16
- package/docs/pt/intlayer_with_vanilla.md +506 -0
- package/docs/ru/cli/index.md +54 -42
- package/docs/ru/cli/init.md +31 -27
- package/docs/ru/cli/standalone.md +91 -0
- package/docs/ru/configuration.md +46 -7
- package/docs/ru/custom_domains.md +250 -0
- package/docs/ru/intlayer_with_tanstack+solid.md +14 -33
- package/docs/ru/intlayer_with_tanstack.md +25 -16
- package/docs/ru/intlayer_with_vanilla.md +506 -0
- package/docs/tr/cli/index.md +64 -52
- package/docs/tr/cli/init.md +37 -30
- package/docs/tr/cli/standalone.md +91 -0
- package/docs/tr/configuration.md +46 -7
- package/docs/tr/custom_domains.md +250 -0
- package/docs/tr/intlayer_with_tanstack+solid.md +14 -33
- package/docs/tr/intlayer_with_tanstack.md +25 -16
- package/docs/tr/intlayer_with_vanilla.md +506 -0
- package/docs/uk/cli/index.md +60 -55
- package/docs/uk/cli/init.md +32 -20
- package/docs/uk/cli/standalone.md +91 -0
- package/docs/uk/configuration.md +46 -7
- package/docs/uk/custom_domains.md +250 -0
- package/docs/uk/intlayer_with_tanstack+solid.md +14 -33
- package/docs/uk/intlayer_with_tanstack.md +25 -16
- package/docs/uk/intlayer_with_vanilla.md +506 -0
- package/docs/ur/cli/index.md +195 -0
- package/docs/ur/cli/init.md +96 -0
- package/docs/ur/cli/standalone.md +91 -0
- package/docs/ur/configuration.md +46 -7
- package/docs/ur/custom_domains.md +250 -0
- package/docs/ur/intlayer_with_vanilla.md +506 -0
- package/docs/vi/cli/index.md +72 -61
- package/docs/vi/cli/init.md +33 -21
- package/docs/vi/cli/standalone.md +91 -0
- package/docs/vi/configuration.md +46 -7
- package/docs/vi/custom_domains.md +250 -0
- package/docs/vi/intlayer_with_tanstack+solid.md +14 -33
- package/docs/vi/intlayer_with_tanstack.md +25 -16
- package/docs/vi/intlayer_with_vanilla.md +506 -0
- package/docs/zh/cli/index.md +56 -49
- package/docs/zh/cli/init.md +30 -18
- package/docs/zh/cli/standalone.md +91 -0
- package/docs/zh/configuration.md +46 -7
- package/docs/zh/custom_domains.md +250 -0
- package/docs/zh/intlayer_with_tanstack+solid.md +14 -33
- package/docs/zh/intlayer_with_tanstack.md +25 -16
- package/docs/zh/intlayer_with_vanilla.md +506 -0
- package/package.json +8 -8
- package/src/doc.ts +4 -1
- package/src/generated/docs.entry.ts +60 -0
- package/docs/ar/bundle_optimization.md +0 -185
- package/docs/de/bundle_optimization.md +0 -195
- package/docs/en-GB/bundle_optimization.md +0 -184
- package/docs/es/bundle_optimization.md +0 -194
- package/docs/fr/bundle_optimization.md +0 -184
- package/docs/hi/bundle_optimization.md +0 -185
- package/docs/id/bundle_optimization.md +0 -185
- package/docs/it/bundle_optimization.md +0 -185
- package/docs/ja/bundle_optimization.md +0 -185
- package/docs/ko/bundle_optimization.md +0 -185
- package/docs/pl/bundle_optimization.md +0 -185
- package/docs/pt/bundle_optimization.md +0 -184
- package/docs/ru/bundle_optimization.md +0 -185
- package/docs/tr/bundle_optimization.md +0 -184
- package/docs/uk/bundle_optimization.md +0 -186
- package/docs/vi/bundle_optimization.md +0 -185
- package/docs/zh/bundle_optimization.md +0 -185
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-04-02
|
|
3
|
+
updatedAt: 2026-04-02
|
|
4
|
+
title: Eigene Domains
|
|
5
|
+
description: Erfahren Sie, wie Sie das domänenbasierte Locale-Routing in Intlayer konfigurieren, um verschiedene Locales über dedizierte Hostnamen bereitzustellen.
|
|
6
|
+
keywords:
|
|
7
|
+
- Eigene Domains
|
|
8
|
+
- Domain-Routing
|
|
9
|
+
- Routing
|
|
10
|
+
- Internationalisierung
|
|
11
|
+
- i18n
|
|
12
|
+
slugs:
|
|
13
|
+
- doc
|
|
14
|
+
- concept
|
|
15
|
+
- custom_domains
|
|
16
|
+
history:
|
|
17
|
+
- version: 8.5.0
|
|
18
|
+
date: 2026-04-02
|
|
19
|
+
changes: "Domänenbasiertes Locale-Routing über die Konfiguration routing.domains hinzugefügt."
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Eigene Domains
|
|
23
|
+
|
|
24
|
+
Intlayer unterstützt domänenbasiertes Locale-Routing, sodass Sie spezifische Locales über dedizierte Hostnamen bereitstellen können. Beispielsweise können chinesische Besucher auf `intlayer.zh` anstatt auf `intlayer.org/zh` geleitet werden.
|
|
25
|
+
|
|
26
|
+
## Funktionsweise
|
|
27
|
+
|
|
28
|
+
Die `domains`-Map in `routing` ordnet jeder Locale einen Hostnamen zu. Intlayer verwendet diese Map an zwei Stellen:
|
|
29
|
+
|
|
30
|
+
1. **URL-Generierung** (`getLocalizedUrl`): Wenn sich die Ziel-Locale auf einer _anderen_ Domain als die aktuelle Seite befindet, wird eine absolute URL zurückgegeben (z. B. `https://intlayer.zh/about`). Wenn beide Domains übereinstimmen, wird eine relative URL zurückgegeben (z. B. `/fr/about`).
|
|
31
|
+
2. **Server-Proxy** (Next.js & Vite): Eingehende Anfragen werden basierend auf der Domain, auf der sie ankommen, umgeleitet oder umgeschrieben.
|
|
32
|
+
|
|
33
|
+
### Exklusive vs. gemeinsame Domains
|
|
34
|
+
|
|
35
|
+
Der entscheidende Unterschied ist die **Exklusivität**:
|
|
36
|
+
|
|
37
|
+
- **Exklusive Domain** — Nur eine Locale wird diesem Hostnamen zugeordnet (z. B. `zh → intlayer.zh`). Die Domain selbst identifiziert die Locale, daher wird dem Pfad kein Locale-Präfix hinzugefügt. `https://intlayer.zh/about` stellt chinesische Inhalte bereit.
|
|
38
|
+
- **Gemeinsame Domain** — Mehrere Locales werden demselben Hostnamen zugeordnet (z. B. werden sowohl `en` als auch `fr` auf `intlayer.org` abgebildet). Es gilt das normale präfixbasierte Routing. `intlayer.org/fr/about` stellt französische Inhalte bereit.
|
|
39
|
+
|
|
40
|
+
## Konfiguration
|
|
41
|
+
|
|
42
|
+
```typescript fileName="intlayer.config.ts"
|
|
43
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
44
|
+
|
|
45
|
+
const config: IntlayerConfig = {
|
|
46
|
+
internationalization: {
|
|
47
|
+
locales: [
|
|
48
|
+
Locales.ENGLISH,
|
|
49
|
+
Locales.FRENCH,
|
|
50
|
+
Locales.SPANISH,
|
|
51
|
+
Locales.CHINESE,
|
|
52
|
+
],
|
|
53
|
+
defaultLocale: Locales.ENGLISH,
|
|
54
|
+
},
|
|
55
|
+
routing: {
|
|
56
|
+
mode: "prefix-no-default",
|
|
57
|
+
domains: {
|
|
58
|
+
// Gemeinsame Domain — en und fr verwenden Präfix-Routing auf intlayer.org
|
|
59
|
+
en: "intlayer.org",
|
|
60
|
+
// Exklusive Domain — zh hat einen eigenen Hostnamen, kein /zh/-Präfix erforderlich
|
|
61
|
+
zh: "intlayer.zh",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export default config;
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Locales, die nicht in `domains` aufgeführt sind, verwenden weiterhin das Standard-Präfix-Routing ohne Domain-Überschreibung.
|
|
70
|
+
|
|
71
|
+
## URL-Generierung
|
|
72
|
+
|
|
73
|
+
`getLocalizedUrl` erzeugt automatisch den richtigen URL-Typ basierend auf dem Aufrufkontext.
|
|
74
|
+
|
|
75
|
+
### Locale auf derselben Domain (relative URL)
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
// Aktuelle Seite: intlayer.org/about
|
|
79
|
+
getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.org" });
|
|
80
|
+
// → "/fr/about"
|
|
81
|
+
|
|
82
|
+
getLocalizedUrl("/about", "en", { currentDomain: "intlayer.org" });
|
|
83
|
+
// → "/about" (Standard-Locale, kein Präfix)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Domainübergreifende Locale (absolute URL)
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// Aktuelle Seite: intlayer.org/about
|
|
90
|
+
getLocalizedUrl("/about", "zh", { currentDomain: "intlayer.org" });
|
|
91
|
+
// → "https://intlayer.zh/about" (exklusive Domain, kein /zh/-Präfix)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Bereitstellung über die eigene Domain der Locale
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
// Aktuelle Seite: intlayer.zh/about
|
|
98
|
+
getLocalizedUrl("/about", "zh", { currentDomain: "intlayer.zh" });
|
|
99
|
+
// → "/about" (bereits auf der richtigen Domain — relative URL)
|
|
100
|
+
|
|
101
|
+
getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.zh" });
|
|
102
|
+
// → "https://intlayer.org/fr/about" (domainübergreifender Link zurück zu intlayer.org)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Automatische Erkennung der aktuellen Domain
|
|
106
|
+
|
|
107
|
+
`currentDomain` ist optional. Wenn es weggelassen wird, löst `getLocalizedUrl` es in dieser Reihenfolge auf:
|
|
108
|
+
|
|
109
|
+
1. Der Hostname einer absoluten Eingabe-URL (z. B. `https://intlayer.org/about` → `intlayer.org`).
|
|
110
|
+
2. `window.location.hostname` in Browserumgebungen.
|
|
111
|
+
3. Wenn keines von beiden verfügbar ist (SSR ohne explizite Option), wird eine relative URL für Locales auf derselben Domain zurückgegeben und keine absolute URL erzeugt — dies ist der sichere Fallback.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// Browser — window.location.hostname === 'intlayer.org'
|
|
115
|
+
getLocalizedUrl("/about", "zh");
|
|
116
|
+
// → "https://intlayer.zh/about" (automatisch von window erkannt)
|
|
117
|
+
|
|
118
|
+
// Von einer absoluten URL — Domain automatisch erkannt
|
|
119
|
+
getLocalizedUrl("https://intlayer.org/about", "zh");
|
|
120
|
+
// → "https://intlayer.zh/about"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `getMultilingualUrls` mit Domains
|
|
124
|
+
|
|
125
|
+
`getMultilingualUrls` ruft `getLocalizedUrl` für jede Locale auf, sodass je nach Domain des Aufrufers eine Mischung aus relativen und absoluten URLs erzeugt wird:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
// currentDomain: 'intlayer.org'
|
|
129
|
+
getMultilingualUrls("/about", { currentDomain: "intlayer.org" });
|
|
130
|
+
// {
|
|
131
|
+
// en: "/about",
|
|
132
|
+
// fr: "/fr/about",
|
|
133
|
+
// es: "/es/about",
|
|
134
|
+
// zh: "https://intlayer.zh/about",
|
|
135
|
+
// }
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Diese absoluten URLs können direkt in `<link rel="alternate" hreflang="...">`-Tags für SEO verwendet werden.
|
|
139
|
+
|
|
140
|
+
## Proxy-Verhalten
|
|
141
|
+
|
|
142
|
+
### Next.js
|
|
143
|
+
|
|
144
|
+
Die `intlayerProxy`-Middleware übernimmt das Domain-Routing automatisch. Fügen Sie sie zu Ihrer `middleware.ts` hinzu:
|
|
145
|
+
|
|
146
|
+
```typescript fileName="middleware.ts"
|
|
147
|
+
export { intlayerProxy as default } from "next-intlayer/proxy";
|
|
148
|
+
|
|
149
|
+
export const config = {
|
|
150
|
+
matcher: "/((?!api|static|assets|robots|sitemap|.*\\..*|_next).*)",
|
|
151
|
+
};
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Redirect** — Anfrage kommt auf der falschen Domain für ein bestimmtes Locale-Präfix an:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
GET intlayer.org/zh/about
|
|
158
|
+
→ 301 https://intlayer.zh/about
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Rewrite** — Anfrage kommt auf der exklusiven Domain der Locale ohne Präfix an:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
GET intlayer.zh/about
|
|
165
|
+
→ Rewrite zu /zh/about (nur internes Next.js-Routing, URL bleibt sauber)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Vite
|
|
169
|
+
|
|
170
|
+
Das `intlayerProxy` Vite-Plugin wendet die gleiche Logik während der Entwicklung an:
|
|
171
|
+
|
|
172
|
+
```typescript fileName="vite.config.ts"
|
|
173
|
+
import { defineConfig } from "vite";
|
|
174
|
+
import { intlayerProxy } from "vite-intlayer";
|
|
175
|
+
|
|
176
|
+
export default defineConfig({
|
|
177
|
+
plugins: [intlayerProxy()],
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
> **Hinweis**: Bei der lokalen Entwicklung befinden Sie sich normalerweise auf `localhost`, daher weisen domainübergreifende Umleitungen auf die Live-Domains anstatt auf einen anderen lokalen Port hin. Verwenden Sie ein Überschreiben der hosts-Datei (z. B. `127.0.0.1 intlayer.zh`) oder einen Reverse-Proxy, wenn Sie das Multi-Domain-Routing lokal testen müssen.
|
|
182
|
+
|
|
183
|
+
## Locale-Switcher
|
|
184
|
+
|
|
185
|
+
Der `useLocale`-Hook von `next-intlayer` übernimmt die domänenbewusste Navigation automatisch. Wenn ein Benutzer zu einer Locale auf einer anderen Domain wechselt, führt der Hook eine vollständige Seitennavigation (`window.location.href`) anstelle eines clientseitigen Router-Pushs durch, da der Next.js-Router keine Ursprungsgrenzen überschreiten kann.
|
|
186
|
+
|
|
187
|
+
```tsx fileName="components/LocaleSwitcher.tsx"
|
|
188
|
+
"use client";
|
|
189
|
+
|
|
190
|
+
import { useLocale } from "next-intlayer";
|
|
191
|
+
|
|
192
|
+
export const LocaleSwitcher = () => {
|
|
193
|
+
const { availableLocales, locale, setLocale } = useLocale();
|
|
194
|
+
|
|
195
|
+
return (
|
|
196
|
+
<ul>
|
|
197
|
+
{availableLocales.map((localeEl) => (
|
|
198
|
+
<li key={localeEl}>
|
|
199
|
+
<button
|
|
200
|
+
onClick={() => setLocale(localeEl)}
|
|
201
|
+
aria-current={localeEl === locale ? "true" : undefined}
|
|
202
|
+
>
|
|
203
|
+
{l.toUpperCase()}
|
|
204
|
+
</button>
|
|
205
|
+
</li>
|
|
206
|
+
))}
|
|
207
|
+
</ul>
|
|
208
|
+
);
|
|
209
|
+
};
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Es ist keine zusätzliche Konfiguration erforderlich — `useLocale` erkennt intern `window.location.hostname` und entscheidet zwischen `router.replace` (gleiche Domain) und `window.location.href` (domainübergreifend).
|
|
213
|
+
|
|
214
|
+
## SEO: `hreflang` Alternate Links
|
|
215
|
+
|
|
216
|
+
Domänenbasiertes Routing wird häufig zusammen mit `hreflang` verwendet, um Suchmaschinen mitzuteilen, welche URL für welche Sprache indexiert werden soll. Verwenden Sie `getMultilingualUrls`, um den vollständigen Satz alternativer URLs zu generieren:
|
|
217
|
+
|
|
218
|
+
```tsx fileName="app/[locale]/layout.tsx"
|
|
219
|
+
import { getMultilingualUrls } from "intlayer";
|
|
220
|
+
import type { Metadata } from "next";
|
|
221
|
+
|
|
222
|
+
export const generateMetadata = (): Metadata => {
|
|
223
|
+
const alternates = getMultilingualUrls("/", {
|
|
224
|
+
currentDomain: process.env.NEXT_PUBLIC_DOMAIN, // z. B. "intlayer.org"
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
alternates: {
|
|
229
|
+
languages: alternates,
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Dies erzeugt:
|
|
236
|
+
|
|
237
|
+
```html
|
|
238
|
+
<link rel="alternate" hreflang="en" href="https://intlayer.org/" />
|
|
239
|
+
<link rel="alternate" hreflang="fr" href="https://intlayer.org/fr/" />
|
|
240
|
+
<link rel="alternate" hreflang="es" href="https://intlayer.org/es/" />
|
|
241
|
+
<link rel="alternate" hreflang="zh" href="https://intlayer.zh/" />
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Kern-Utilities
|
|
245
|
+
|
|
246
|
+
| Utility | Beschreibung |
|
|
247
|
+
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
248
|
+
| `getLocalizedUrl(url, locale, { currentDomain })` | Gibt eine relative oder absolute URL zurück, je nachdem, ob sich die Ziel-Locale auf der aktuellen Domain befindet. |
|
|
249
|
+
| `getMultilingualUrls(url, { currentDomain })` | Gibt eine Map lokalisierter URLs zurück, wobei relative und absolute URLs nach Bedarf gemischt werden. |
|
|
250
|
+
| `getPrefix(locale, { domains })` | Gibt ein leeres Präfix für Locales mit exklusiver Domain zurück, ansonsten das normale Präfix. |
|
|
@@ -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:
|
|
@@ -163,59 +164,45 @@ export default defineConfig({
|
|
|
163
164
|
|
|
164
165
|
### Schritt 5: Root-Layout erstellen
|
|
165
166
|
|
|
166
|
-
Konfigurieren Sie Ihr Root-Layout für die Internationalisierung, indem Sie `
|
|
167
|
+
Konfigurieren Sie Ihr Root-Layout für die Internationalisierung, indem Sie `useParams` verwenden, um das aktuelle Gebietsschema zu erkennen und die Attribute `lang` und `dir` für das `html`-Tag festzulegen.
|
|
167
168
|
|
|
168
169
|
```tsx fileName="src/routes/__root.tsx"
|
|
169
170
|
import {
|
|
170
171
|
HeadContent,
|
|
171
|
-
Outlet,
|
|
172
172
|
Scripts,
|
|
173
173
|
createRootRouteWithContext,
|
|
174
|
-
useMatches,
|
|
175
174
|
} from "@tanstack/solid-router";
|
|
176
|
-
import { TanStackRouterDevtools } from "@tanstack/solid-router-devtools";
|
|
177
175
|
import { HydrationScript } from "solid-js/web";
|
|
178
|
-
import { Suspense } from "solid-js";
|
|
176
|
+
import { Suspense, type ParentComponent } from "solid-js";
|
|
179
177
|
import { IntlayerProvider } from "solid-intlayer";
|
|
180
|
-
import { defaultLocale, getHTMLTextDir
|
|
178
|
+
import { defaultLocale, getHTMLTextDir } from "intlayer";
|
|
179
|
+
import { Route as LocaleRoute } from "./{-$locale}/route";
|
|
181
180
|
|
|
182
181
|
export const Route = createRootRouteWithContext()({
|
|
183
182
|
shellComponent: RootComponent,
|
|
184
183
|
});
|
|
185
184
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
function RootComponent() {
|
|
191
|
-
const matches = useMatches();
|
|
192
|
-
|
|
193
|
-
// Versuchen, das Gebietsschema in den Parametern eines passenden Elements zu finden
|
|
194
|
-
// Dies setzt voraus, dass Sie das dynamische Segment "/{-$locale}" in Ihrem Routenbaum verwenden
|
|
195
|
-
const locale =
|
|
196
|
-
(
|
|
197
|
-
matches().find((match) => match.routeId === "/{-$locale}/")
|
|
198
|
-
?.params as Params
|
|
199
|
-
)?.locale ?? defaultLocale;
|
|
185
|
+
const RootComponent: ParentComponent = (props) => {
|
|
186
|
+
const params = LocaleRoute.useParams();
|
|
187
|
+
const locale = params()?.locale ?? defaultLocale;
|
|
200
188
|
|
|
201
189
|
return (
|
|
202
190
|
<html dir={getHTMLTextDir(locale)} lang={locale}>
|
|
203
191
|
<head>
|
|
204
192
|
<HydrationScript />
|
|
193
|
+
<HeadContent />
|
|
205
194
|
</head>
|
|
206
195
|
<body>
|
|
207
|
-
<HeadContent />
|
|
208
196
|
<IntlayerProvider locale={locale}>
|
|
209
197
|
<Suspense>
|
|
210
|
-
|
|
211
|
-
<TanStackRouterDevtools />
|
|
198
|
+
{props.children}
|
|
212
199
|
</Suspense>
|
|
213
200
|
</IntlayerProvider>
|
|
214
201
|
<Scripts />
|
|
215
202
|
</body>
|
|
216
203
|
</html>
|
|
217
204
|
);
|
|
218
|
-
}
|
|
205
|
+
};
|
|
219
206
|
```
|
|
220
207
|
|
|
221
208
|
### Schritt 6: Gebietsschema-Layout erstellen (Optional)
|
|
@@ -459,18 +446,12 @@ export default LocaleSwitcher;
|
|
|
459
446
|
|
|
460
447
|
### Schritt 11: Verwaltung von HTML-Attributen
|
|
461
448
|
|
|
462
|
-
Wie in Schritt 5 zu sehen ist, können Sie die Attribute `lang` und `dir` des `html`-Tags mit `
|
|
449
|
+
Wie in Schritt 5 zu sehen ist, können Sie die Attribute `lang` und `dir` des `html`-Tags mit `useParams` in Ihrer Root-Komponente verwalten. Dies stellt sicher, dass die korrekten Attribute auf dem Server und dem Client festgelegt werden.
|
|
463
450
|
|
|
464
451
|
```tsx fileName="src/routes/__root.tsx"
|
|
465
452
|
const RootComponent: ParentComponent = (props) => {
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
// Versuchen, das Gebietsschema in den Parametern einer passenden Route zu finden
|
|
469
|
-
const locale =
|
|
470
|
-
(
|
|
471
|
-
matches().find((match) => match.routeId === "/{-$locale}/")
|
|
472
|
-
?.params as Params
|
|
473
|
-
)?.locale ?? defaultLocale;
|
|
453
|
+
const params = LocaleRoute.useParams();
|
|
454
|
+
const locale = params()?.locale ?? defaultLocale;
|
|
474
455
|
|
|
475
456
|
return (
|
|
476
457
|
<html dir={getHTMLTextDir(locale)} lang={locale}>
|
|
@@ -183,31 +183,41 @@ export default config;
|
|
|
183
183
|
|
|
184
184
|
### Schritt 5: Root-Layout erstellen
|
|
185
185
|
|
|
186
|
-
Konfigurieren Sie Ihr Root-Layout zur Unterstützung der Internationalisierung, indem Sie `
|
|
186
|
+
Konfigurieren Sie Ihr Root-Layout zur Unterstützung der Internationalisierung, indem Sie `useParams` verwenden, um die aktuelle Locale zu erkennen und die Attribute `lang` und `dir` für das `html`-Tag festzulegen.
|
|
187
187
|
|
|
188
188
|
```tsx fileName="src/routes/__root.tsx"
|
|
189
189
|
import {
|
|
190
190
|
createRootRouteWithContext,
|
|
191
191
|
HeadContent,
|
|
192
|
-
Outlet,
|
|
193
192
|
Scripts,
|
|
194
|
-
useMatches,
|
|
195
193
|
} from "@tanstack/react-router";
|
|
196
194
|
import { defaultLocale, getHTMLTextDir } from "intlayer";
|
|
197
195
|
import { type ReactNode } from "react";
|
|
198
196
|
import { IntlayerProvider } from "react-intlayer";
|
|
197
|
+
import { Route as LocaleRoute } from "./{-$locale}/route";
|
|
199
198
|
|
|
200
199
|
export const Route = createRootRouteWithContext<{}>()({
|
|
200
|
+
head: () => ({
|
|
201
|
+
meta: [
|
|
202
|
+
{
|
|
203
|
+
charSet: "utf-8",
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
content: "width=device-width, initial-scale=1",
|
|
207
|
+
name: "viewport",
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
title: "TanStack Start Starter",
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
}),
|
|
214
|
+
|
|
201
215
|
shellComponent: RootDocument,
|
|
202
216
|
});
|
|
203
217
|
|
|
204
218
|
function RootDocument({ children }: { children: ReactNode }) {
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
// Versuchen, die Locale in den Parametern eines aktiven Matches zu finden
|
|
208
|
-
// Dies setzt voraus, dass Sie das dynamische Segment "/{-$locale}" in Ihrem Routenbaum verwenden
|
|
209
|
-
const localeRoute = matches.find((match) => match.routeId === "/{-$locale}");
|
|
210
|
-
const locale = localeRoute?.params?.locale ?? defaultLocale;
|
|
219
|
+
const params = LocaleRoute.useParams();
|
|
220
|
+
const locale = params?.locale ?? defaultLocale;
|
|
211
221
|
|
|
212
222
|
return (
|
|
213
223
|
<html dir={getHTMLTextDir(locale)} lang={locale}>
|
|
@@ -215,7 +225,9 @@ function RootDocument({ children }: { children: ReactNode }) {
|
|
|
215
225
|
<HeadContent />
|
|
216
226
|
</head>
|
|
217
227
|
<body>
|
|
218
|
-
<IntlayerProvider locale={locale}>
|
|
228
|
+
<IntlayerProvider locale={locale}>
|
|
229
|
+
{children}
|
|
230
|
+
</IntlayerProvider>
|
|
219
231
|
<Scripts />
|
|
220
232
|
</body>
|
|
221
233
|
</html>
|
|
@@ -558,15 +570,12 @@ export const LocaleSwitcher: FC = () => {
|
|
|
558
570
|
|
|
559
571
|
### Schritt 10: HTML-Attribute-Verwaltung
|
|
560
572
|
|
|
561
|
-
Wie in Schritt 5 gezeigt, können Sie die Attribute `lang` und `dir` des `html`-Tags mit `
|
|
573
|
+
Wie in Schritt 5 gezeigt, können Sie die Attribute `lang` und `dir` des `html`-Tags mit `useParams` in Ihrer Root-Komponente verwalten. Dies stellt sicher, dass die richtigen Attribute auf dem Server und dem Client gesetzt werden.
|
|
562
574
|
|
|
563
575
|
```tsx fileName="src/routes/__root.tsx"
|
|
564
576
|
function RootDocument({ children }: { children: ReactNode }) {
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
// Versuchen, die Locale in den Parametern eines aktiven Matches zu finden
|
|
568
|
-
const localeRoute = matches.find((match) => match.routeId === "/{-$locale}");
|
|
569
|
-
const locale = localeRoute?.params?.locale ?? defaultLocale;
|
|
577
|
+
const params = LocaleRoute.useParams();
|
|
578
|
+
const locale = params?.locale ?? defaultLocale;
|
|
570
579
|
|
|
571
580
|
return (
|
|
572
581
|
<html dir={getHTMLTextDir(locale)} lang={locale}>
|