@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: Domain Kustom
|
|
5
|
+
description: Pelajari cara mengonfigurasi perutean lokal berbasis domain di Intlayer untuk menyajikan berbagai lokal dari nama host khusus.
|
|
6
|
+
keywords:
|
|
7
|
+
- Domain Kustom
|
|
8
|
+
- Perutean Domain
|
|
9
|
+
- Perutean
|
|
10
|
+
- Internasionalisasi
|
|
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: "Tambahkan perutean lokal berbasis domain melalui konfigurasi routing.domains."
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Domain Kustom
|
|
23
|
+
|
|
24
|
+
Intlayer mendukung perutean lokal berbasis domain, yang memungkinkan Anda menyajikan lokal tertentu dari nama host khusus. Misalnya, pengunjung dari Tiongkok dapat diarahkan ke `intlayer.zh` daripada `intlayer.org/zh`.
|
|
25
|
+
|
|
26
|
+
## Cara Kerjanya
|
|
27
|
+
|
|
28
|
+
Peta `domains` di dalam `routing` mengaitkan setiap lokal dengan nama host. Intlayer menggunakan peta ini di dua tempat:
|
|
29
|
+
|
|
30
|
+
1. **Pembuatan URL** (`getLocalizedUrl`): saat lokal target berada pada domain yang _berbeda_ dari halaman saat ini, URL absolut akan dikembalikan (misalnya `https://intlayer.zh/about`). Saat kedua domain cocok, URL relatif akan dikembalikan (misalnya `/fr/about`).
|
|
31
|
+
2. **Proksi server** (Next.js & Vite): permintaan masuk akan dialihkan atau ditulis ulang berdasarkan domain tempat mereka tiba.
|
|
32
|
+
|
|
33
|
+
### Domain eksklusif vs. bersama
|
|
34
|
+
|
|
35
|
+
Perbedaan utamanya adalah **eksklusivitas**:
|
|
36
|
+
|
|
37
|
+
- **Domain eksklusif** — hanya satu lokal yang memetakan ke nama host tersebut (misalnya `zh → intlayer.zh`). Domain itu sendiri bertindak sebagai pengidentifikasi lokal, sehingga tidak ada awalan lokal yang ditambahkan ke jalur. `https://intlayer.zh/about` menyajikan konten bahasa Mandarin.
|
|
38
|
+
- **Domain bersama** — beberapa lokal memetakan ke nama host yang sama (misalnya `en` dan `fr` keduanya memetakan ke `intlayer.org`). Perutean berbasis awalan normal berlaku. `intlayer.org/fr/about` menyajikan konten bahasa Prancis.
|
|
39
|
+
|
|
40
|
+
## Konfigurasi
|
|
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
|
+
// Domain bersama — en dan fr menggunakan perutean awalan pada intlayer.org
|
|
59
|
+
en: "intlayer.org",
|
|
60
|
+
// Domain eksklusif — zh memiliki nama host sendiri, tidak perlu awalan /zh/
|
|
61
|
+
zh: "intlayer.zh",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export default config;
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Lokal yang tidak tercantum dalam `domains` terus menggunakan perutean awalan standar tanpa penggantian domain apa pun.
|
|
70
|
+
|
|
71
|
+
## Pembuatan URL
|
|
72
|
+
|
|
73
|
+
`getLocalizedUrl` secara otomatis menghasilkan jenis URL yang benar berdasarkan konteks pemanggilan.
|
|
74
|
+
|
|
75
|
+
### Lokal domain yang sama (URL relatif)
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
// Halaman saat ini: intlayer.org/about
|
|
79
|
+
getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.org" });
|
|
80
|
+
// → "/fr/about"
|
|
81
|
+
|
|
82
|
+
getLocalizedUrl("/about", "en", { currentDomain: "intlayer.org" });
|
|
83
|
+
// → "/about" (lokal default, tanpa awalan)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Lokal lintas domain (URL absolut)
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// Halaman saat ini: intlayer.org/about
|
|
90
|
+
getLocalizedUrl("/about", "zh", { currentDomain: "intlayer.org" });
|
|
91
|
+
// → "https://intlayer.zh/about" (domain eksklusif, tanpa awalan /zh/)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Menyajikan dari domain lokal itu sendiri
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
// Halaman saat ini: intlayer.zh/about
|
|
98
|
+
getLocalizedUrl("/about", "zh", { currentDomain: "intlayer.zh" });
|
|
99
|
+
// → "/about" (sudah berada di domain yang benar — URL relatif)
|
|
100
|
+
|
|
101
|
+
getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.zh" });
|
|
102
|
+
// → "https://intlayer.org/fr/about" (tautan lintas domain kembali ke intlayer.org)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Deteksi otomatis domain saat ini
|
|
106
|
+
|
|
107
|
+
`currentDomain` bersifat opsional. Jika dihilangkan, `getLocalizedUrl` menyelesaikannya dalam urutan ini:
|
|
108
|
+
|
|
109
|
+
1. Nama host dari URL input absolut (misalnya `https://intlayer.org/about` → `intlayer.org`).
|
|
110
|
+
2. `window.location.hostname` di lingkungan peramban.
|
|
111
|
+
3. Jika keduanya tidak tersedia (SSR tanpa opsi eksplisit), URL relatif akan dikembalikan untuk lokal domain yang sama dan tidak ada URL absolut yang dihasilkan — ini adalah fallback yang aman.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// Peramban — window.location.hostname === 'intlayer.org'
|
|
115
|
+
getLocalizedUrl("/about", "zh");
|
|
116
|
+
// → "https://intlayer.zh/about" (dideteksi otomatis dari jendela)
|
|
117
|
+
|
|
118
|
+
// Dari URL absolut — domain terdeteksi secara otomatis
|
|
119
|
+
getLocalizedUrl("https://intlayer.org/about", "zh");
|
|
120
|
+
// → "https://intlayer.zh/about"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `getMultilingualUrls` dengan domain
|
|
124
|
+
|
|
125
|
+
`getMultilingualUrls` memanggil `getLocalizedUrl` untuk setiap lokal, sehingga menghasilkan campuran URL relatif dan absolut tergantung pada domain pemanggil:
|
|
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
|
+
URL absolut ini siap digunakan dalam tag `<link rel="alternate" hreflang="...">` untuk SEO.
|
|
139
|
+
|
|
140
|
+
## Perilaku Proksi
|
|
141
|
+
|
|
142
|
+
### Next.js
|
|
143
|
+
|
|
144
|
+
Middleware `intlayerProxy` menangani perutean domain secara otomatis. Tambahkan ke `middleware.ts` Anda:
|
|
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** — permintaan tiba di domain yang salah untuk awalan lokal tertentu:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
GET intlayer.org/zh/about
|
|
158
|
+
→ 301 https://intlayer.zh/about
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Rewrite** — permintaan tiba di domain eksklusif lokal tanpa awalan:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
GET intlayer.zh/about
|
|
165
|
+
→ tulis ulang ke /zh/about (hanya perutean internal Next.js, URL tetap bersih)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Vite
|
|
169
|
+
|
|
170
|
+
Plugin Vite `intlayerProxy` menerapkan logika yang sama selama pengembangan:
|
|
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
|
+
> **Catatan**: dalam pengembangan lokal Anda biasanya menggunakan `localhost`, sehingga pengalihan lintas domain akan mengarah ke domain langsung alih-alih port lokal lainnya. Gunakan penggantian file hosts (misalnya `127.0.0.1 intlayer.zh`) atau proksi terbalik jika Anda perlu menguji perutean multi-domain secara lokal.
|
|
182
|
+
|
|
183
|
+
## Pemilih Lokal (Locale Switcher)
|
|
184
|
+
|
|
185
|
+
Hook `useLocale` dari `next-intlayer` menangani navigasi sadar domain secara otomatis. Saat pengguna beralih ke lokal di domain yang berbeda, hook melakukan navigasi halaman penuh (`window.location.href`) alih-alih router push sisi klien, karena router Next.js tidak dapat melintasi asal (origins).
|
|
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((l) => (
|
|
198
|
+
<li key={l}>
|
|
199
|
+
<button
|
|
200
|
+
onClick={() => setLocale(l)}
|
|
201
|
+
aria-current={l === locale ? "true" : undefined}
|
|
202
|
+
>
|
|
203
|
+
{l.toUpperCase()}
|
|
204
|
+
</button>
|
|
205
|
+
</li>
|
|
206
|
+
))}
|
|
207
|
+
</ul>
|
|
208
|
+
);
|
|
209
|
+
};
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Tidak diperlukan konfigurasi tambahan — `useLocale` mendeteksi `window.location.hostname` secara internal dan memutuskan antara `router.replace` (domain yang sama) dan `window.location.href` (lintas domain).
|
|
213
|
+
|
|
214
|
+
## SEO: Tautan Alternatif `hreflang`
|
|
215
|
+
|
|
216
|
+
Perutean berbasis domain biasanya digunakan bersama dengan `hreflang` untuk memberi tahu mesin telusur URL mana yang harus diindeks untuk setiap bahasa. Gunakan `getMultilingualUrls` untuk menghasilkan set lengkap URL alternatif:
|
|
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, // mis. "intlayer.org"
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
alternates: {
|
|
229
|
+
languages: alternates,
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Ini menghasilkan:
|
|
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
|
+
## Utilitas Inti
|
|
245
|
+
|
|
246
|
+
| Utilitas | Deskripsi |
|
|
247
|
+
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
248
|
+
| `getLocalizedUrl(url, locale, { currentDomain })` | Mengembalikan URL relatif atau absolut tergantung pada apakah lokal target berada di domain saat ini. |
|
|
249
|
+
| `getMultilingualUrls(url, { currentDomain })` | Mengembalikan peta URL lokal yang diberi kunci lokal, mencampur relatif dan absolut sesuai kebutuhan. |
|
|
250
|
+
| `getPrefix(locale, { domains })` | Mengembalikan awalan kosong untuk lokal domain eksklusif, awalan normal jika sebaliknya. |
|
|
@@ -16,6 +16,7 @@ slugs:
|
|
|
16
16
|
- doc
|
|
17
17
|
- environment
|
|
18
18
|
- tanstack-start
|
|
19
|
+
- solid
|
|
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:
|
|
@@ -162,59 +163,45 @@ export default defineConfig({
|
|
|
162
163
|
|
|
163
164
|
### Langkah 5: Buat Root Layout
|
|
164
165
|
|
|
165
|
-
Konfigurasikan root layout Anda untuk mendukung internasionalisasi dengan menggunakan `
|
|
166
|
+
Konfigurasikan root layout Anda untuk mendukung internasionalisasi dengan menggunakan `useParams` untuk mendeteksi lokal saat ini dan mengatur atribut `lang` serta `dir` pada tag `html`.
|
|
166
167
|
|
|
167
168
|
```tsx fileName="src/routes/__root.tsx"
|
|
168
169
|
import {
|
|
169
170
|
HeadContent,
|
|
170
|
-
Outlet,
|
|
171
171
|
Scripts,
|
|
172
172
|
createRootRouteWithContext,
|
|
173
|
-
useMatches,
|
|
174
173
|
} from "@tanstack/solid-router";
|
|
175
|
-
import { TanStackRouterDevtools } from "@tanstack/solid-router-devtools";
|
|
176
174
|
import { HydrationScript } from "solid-js/web";
|
|
177
|
-
import { Suspense } from "solid-js";
|
|
175
|
+
import { Suspense, type ParentComponent } from "solid-js";
|
|
178
176
|
import { IntlayerProvider } from "solid-intlayer";
|
|
179
|
-
import { defaultLocale, getHTMLTextDir
|
|
177
|
+
import { defaultLocale, getHTMLTextDir } from "intlayer";
|
|
178
|
+
import { Route as LocaleRoute } from "./{-$locale}/route";
|
|
180
179
|
|
|
181
180
|
export const Route = createRootRouteWithContext()({
|
|
182
181
|
shellComponent: RootComponent,
|
|
183
182
|
});
|
|
184
183
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
function RootComponent() {
|
|
190
|
-
const matches = useMatches();
|
|
191
|
-
|
|
192
|
-
// Mencoba menemukan lokal dalam parameter dari setiap kecocokan yang aktif
|
|
193
|
-
// Ini mengasumsikan Anda menggunakan segmen dinamis "/{-$locale}" dalam pohon rute Anda
|
|
194
|
-
const locale =
|
|
195
|
-
(
|
|
196
|
-
matches().find((match) => match.routeId === "/{-$locale}/")
|
|
197
|
-
?.params as Params
|
|
198
|
-
)?.locale ?? defaultLocale;
|
|
184
|
+
const RootComponent: ParentComponent = (props) => {
|
|
185
|
+
const params = LocaleRoute.useParams();
|
|
186
|
+
const locale = params()?.locale ?? defaultLocale;
|
|
199
187
|
|
|
200
188
|
return (
|
|
201
189
|
<html dir={getHTMLTextDir(locale)} lang={locale}>
|
|
202
190
|
<head>
|
|
203
191
|
<HydrationScript />
|
|
192
|
+
<HeadContent />
|
|
204
193
|
</head>
|
|
205
194
|
<body>
|
|
206
|
-
<HeadContent />
|
|
207
195
|
<IntlayerProvider locale={locale}>
|
|
208
196
|
<Suspense>
|
|
209
|
-
|
|
210
|
-
<TanStackRouterDevtools />
|
|
197
|
+
{props.children}
|
|
211
198
|
</Suspense>
|
|
212
199
|
</IntlayerProvider>
|
|
213
200
|
<Scripts />
|
|
214
201
|
</body>
|
|
215
202
|
</html>
|
|
216
203
|
);
|
|
217
|
-
}
|
|
204
|
+
};
|
|
218
205
|
```
|
|
219
206
|
|
|
220
207
|
### Langkah 6: Buat Locale Layout (Opsional)
|
|
@@ -458,18 +445,12 @@ export default LocaleSwitcher;
|
|
|
458
445
|
|
|
459
446
|
### Langkah 11: Pengelolaan Atribut HTML
|
|
460
447
|
|
|
461
|
-
Seperti yang terlihat pada Langkah 5, Anda dapat mengelola atribut `lang` dan `dir` dari tag `html` dengan menggunakan `
|
|
448
|
+
Seperti yang terlihat pada Langkah 5, Anda dapat mengelola atribut `lang` dan `dir` dari tag `html` dengan menggunakan `useParams` di root component Anda. Ini memastikan atribut yang benar disetel baik di server maupun klien.
|
|
462
449
|
|
|
463
450
|
```tsx fileName="src/routes/__root.tsx"
|
|
464
451
|
const RootComponent: ParentComponent = (props) => {
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
// Mencoba menemukan lokal dalam parameter dari setiap kecocokan yang aktif
|
|
468
|
-
const locale =
|
|
469
|
-
(
|
|
470
|
-
matches().find((match) => match.routeId === "/{-$locale}/")
|
|
471
|
-
?.params as Params
|
|
472
|
-
)?.locale ?? defaultLocale;
|
|
452
|
+
const params = LocaleRoute.useParams();
|
|
453
|
+
const locale = params()?.locale ?? defaultLocale;
|
|
473
454
|
|
|
474
455
|
return (
|
|
475
456
|
<html dir={getHTMLTextDir(locale)} lang={locale}>
|
|
@@ -182,31 +182,41 @@ export default config;
|
|
|
182
182
|
|
|
183
183
|
### Langkah 5: Buat Layout Root
|
|
184
184
|
|
|
185
|
-
Konfigurasikan layout root Anda untuk mendukung internasionalisasi dengan menggunakan `
|
|
185
|
+
Konfigurasikan layout root Anda untuk mendukung internasionalisasi dengan menggunakan `useParams` untuk mendeteksi locale saat ini dan mengatur atribut `lang` dan `dir` pada tag `html`.
|
|
186
186
|
|
|
187
187
|
```tsx fileName="src/routes/__root.tsx"
|
|
188
188
|
import {
|
|
189
189
|
createRootRouteWithContext,
|
|
190
190
|
HeadContent,
|
|
191
|
-
Outlet,
|
|
192
191
|
Scripts,
|
|
193
|
-
useMatches,
|
|
194
192
|
} from "@tanstack/react-router";
|
|
195
193
|
import { defaultLocale, getHTMLTextDir } from "intlayer";
|
|
196
194
|
import { type ReactNode } from "react";
|
|
197
195
|
import { IntlayerProvider } from "react-intlayer";
|
|
196
|
+
import { Route as LocaleRoute } from "./{-$locale}/route";
|
|
198
197
|
|
|
199
198
|
export const Route = createRootRouteWithContext<{}>()({
|
|
199
|
+
head: () => ({
|
|
200
|
+
meta: [
|
|
201
|
+
{
|
|
202
|
+
charSet: "utf-8",
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
content: "width=device-width, initial-scale=1",
|
|
206
|
+
name: "viewport",
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
title: "TanStack Start Starter",
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
|
+
}),
|
|
213
|
+
|
|
200
214
|
shellComponent: RootDocument,
|
|
201
215
|
});
|
|
202
216
|
|
|
203
217
|
function RootDocument({ children }: { children: ReactNode }) {
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
// Coba cari locale di params dari match yang aktif
|
|
207
|
-
// Ini mengasumsikan Anda menggunakan segmen dinamis "/{-$locale}" dalam route tree Anda
|
|
208
|
-
const localeRoute = matches.find((match) => match.routeId === "/{-$locale}");
|
|
209
|
-
const locale = localeRoute?.params?.locale ?? defaultLocale;
|
|
218
|
+
const params = LocaleRoute.useParams();
|
|
219
|
+
const locale = params?.locale ?? defaultLocale;
|
|
210
220
|
|
|
211
221
|
return (
|
|
212
222
|
<html dir={getHTMLTextDir(locale)} lang={locale}>
|
|
@@ -214,7 +224,9 @@ function RootDocument({ children }: { children: ReactNode }) {
|
|
|
214
224
|
<HeadContent />
|
|
215
225
|
</head>
|
|
216
226
|
<body>
|
|
217
|
-
<IntlayerProvider locale={locale}>
|
|
227
|
+
<IntlayerProvider locale={locale}>
|
|
228
|
+
{children}
|
|
229
|
+
</IntlayerProvider>
|
|
218
230
|
<Scripts />
|
|
219
231
|
</body>
|
|
220
232
|
</html>
|
|
@@ -557,15 +569,12 @@ export const LocaleSwitcher: FC = () => {
|
|
|
557
569
|
|
|
558
570
|
### Langkah 11: Manajemen Atribut HTML
|
|
559
571
|
|
|
560
|
-
Seperti yang terlihat pada Langkah 5, Anda dapat mengelola atribut `lang` dan `dir` dari tag `html` menggunakan `
|
|
572
|
+
Seperti yang terlihat pada Langkah 5, Anda dapat mengelola atribut `lang` dan `dir` dari tag `html` menggunakan `useParams` di komponen root Anda. Ini memastikan bahwa atribut yang benar diatur pada server dan klien.
|
|
561
573
|
|
|
562
574
|
```tsx fileName="src/routes/__root.tsx"
|
|
563
575
|
function RootDocument({ children }: { children: ReactNode }) {
|
|
564
|
-
const
|
|
565
|
-
|
|
566
|
-
// Coba cari locale di params dari match yang aktif
|
|
567
|
-
const localeRoute = matches.find((match) => match.routeId === "/{-$locale}");
|
|
568
|
-
const locale = localeRoute?.params?.locale ?? defaultLocale;
|
|
576
|
+
const params = LocaleRoute.useParams();
|
|
577
|
+
const locale = params?.locale ?? defaultLocale;
|
|
569
578
|
|
|
570
579
|
return (
|
|
571
580
|
<html dir={getHTMLTextDir(locale)} lang={locale}>
|