@intlayer/docs 7.1.8 → 7.2.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/README.md +1 -0
- package/dist/cjs/generated/docs.entry.cjs +19 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +19 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/intlayer_with_svelte_kit.md +730 -0
- package/docs/ar/intlayer_with_vite+svelte.md +288 -104
- package/docs/de/intlayer_with_svelte_kit.md +730 -0
- package/docs/de/intlayer_with_vite+svelte.md +302 -101
- package/docs/en/intlayer_with_svelte_kit.md +560 -0
- package/docs/en/intlayer_with_vite+svelte.md +153 -15
- package/docs/en/introduction.md +2 -0
- package/docs/en-GB/intlayer_with_svelte_kit.md +730 -0
- package/docs/en-GB/intlayer_with_vite+svelte.md +262 -84
- package/docs/es/intlayer_with_svelte_kit.md +730 -0
- package/docs/es/intlayer_with_vite+svelte.md +300 -107
- package/docs/fr/intlayer_with_svelte_kit.md +762 -0
- package/docs/fr/intlayer_with_vite+svelte.md +297 -101
- package/docs/hi/intlayer_with_svelte_kit.md +730 -0
- package/docs/hi/intlayer_with_vite+svelte.md +298 -108
- package/docs/id/intlayer_with_svelte_kit.md +730 -0
- package/docs/id/intlayer_with_vite+svelte.md +277 -99
- package/docs/it/intlayer_with_svelte_kit.md +762 -0
- package/docs/it/intlayer_with_vite+svelte.md +275 -99
- package/docs/ja/intlayer_with_svelte_kit.md +730 -0
- package/docs/ja/intlayer_with_vite+svelte.md +295 -110
- package/docs/ko/intlayer_with_svelte_kit.md +730 -0
- package/docs/ko/intlayer_with_vite+svelte.md +286 -199
- package/docs/pl/intlayer_with_svelte_kit.md +732 -0
- package/docs/pl/intlayer_with_vite+svelte.md +273 -101
- package/docs/pt/intlayer_with_svelte_kit.md +764 -0
- package/docs/pt/intlayer_with_vite+svelte.md +290 -96
- package/docs/ru/intlayer_with_svelte_kit.md +730 -0
- package/docs/ru/intlayer_with_vite+svelte.md +275 -99
- package/docs/tr/intlayer_with_svelte_kit.md +730 -0
- package/docs/tr/intlayer_with_vite+svelte.md +297 -119
- package/docs/vi/intlayer_with_svelte_kit.md +730 -0
- package/docs/vi/intlayer_with_vite+svelte.md +275 -102
- package/docs/zh/intlayer_with_svelte_kit.md +730 -0
- package/docs/zh/intlayer_with_vite+svelte.md +309 -107
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +19 -0
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-11-20
|
|
3
|
+
updatedAt: 2025-11-20
|
|
4
|
+
title: SvelteKitアプリを翻訳する方法 – i18nガイド 2025
|
|
5
|
+
description: SvelteKitのウェブサイトを多言語対応にする方法を紹介します。Server-Side Rendering(SSR)を使って国際化(i18n)および翻訳を行うためのドキュメントに従ってください。
|
|
6
|
+
keywords:
|
|
7
|
+
- 国際化
|
|
8
|
+
- ドキュメント
|
|
9
|
+
- Intlayer
|
|
10
|
+
- SvelteKit
|
|
11
|
+
- JavaScript
|
|
12
|
+
- SSR
|
|
13
|
+
slugs:
|
|
14
|
+
- doc
|
|
15
|
+
- environment
|
|
16
|
+
- sveltekit
|
|
17
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-sveltekit-template
|
|
18
|
+
history:
|
|
19
|
+
- version: 7.1.10
|
|
20
|
+
date: 2025-11-20
|
|
21
|
+
changes: 初期履歴
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Intlayerを使ってSvelteKitのウェブサイトを翻訳する | 国際化(i18n)
|
|
25
|
+
|
|
26
|
+
## 目次
|
|
27
|
+
|
|
28
|
+
<TOC/>
|
|
29
|
+
|
|
30
|
+
## Intlayerとは何ですか?
|
|
31
|
+
|
|
32
|
+
**Intlayer**は、モダンなウェブアプリケーションにおける多言語対応を簡素化するために設計された革新的なオープンソースの国際化(i18n)ライブラリです。**SvelteKit**のサーバーサイドレンダリング(SSR)機能とシームレスに連携します。
|
|
33
|
+
|
|
34
|
+
Intlayerを使うことで、以下が可能になります:
|
|
35
|
+
|
|
36
|
+
- **コンポーネントレベルで宣言的な辞書を使い、翻訳を簡単に管理**できます。
|
|
37
|
+
- **メタデータ、ルート、コンテンツを動的にローカライズ**できます。
|
|
38
|
+
- **自動生成される型情報でTypeScriptのサポートを保証**します。
|
|
39
|
+
- **SvelteKitのSSRを活用してSEOに優しい国際化を実現**します。
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## SvelteKitアプリケーションでIntlayerをセットアップするステップバイステップガイド
|
|
44
|
+
|
|
45
|
+
まずは新しいSvelteKitプロジェクトを作成しましょう。以下は最終的に作成する構成です:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
.
|
|
49
|
+
├── intlayer.config.ts
|
|
50
|
+
├── package.json
|
|
51
|
+
├── src
|
|
52
|
+
│ ├── app.d.ts
|
|
53
|
+
│ ├── app.html
|
|
54
|
+
│ ├── hooks.server.ts
|
|
55
|
+
│ ├── lib
|
|
56
|
+
│ │ ├── getLocale.ts
|
|
57
|
+
│ │ ├── LocaleSwitcher.svelte
|
|
58
|
+
│ │ └── LocalizedLink.svelte
|
|
59
|
+
│ ├── params
|
|
60
|
+
│ │ └── locale.ts
|
|
61
|
+
│ └── routes
|
|
62
|
+
│ ├── [[locale=locale]]
|
|
63
|
+
│ │ ├── +layout.svelte
|
|
64
|
+
│ │ ├── +layout.ts
|
|
65
|
+
│ │ ├── +page.svelte
|
|
66
|
+
│ │ ├── +page.ts
|
|
67
|
+
│ │ ├── about
|
|
68
|
+
│ │ │ ├── +page.svelte
|
|
69
|
+
│ │ │ ├── +page.ts
|
|
70
|
+
│ │ │ └── page.content.ts
|
|
71
|
+
│ │ ├── Counter.content.ts
|
|
72
|
+
│ │ ├── Counter.svelte
|
|
73
|
+
│ │ ├── Header.content.ts
|
|
74
|
+
│ │ ├── Header.svelte
|
|
75
|
+
│ │ ├── home.content.ts
|
|
76
|
+
│ │ └── layout.content.ts
|
|
77
|
+
│ ├── +layout.svelte
|
|
78
|
+
│ └── layout.css
|
|
79
|
+
├── static
|
|
80
|
+
│ ├── favicon.svg
|
|
81
|
+
│ └── robots.txt
|
|
82
|
+
├── svelte.config.js
|
|
83
|
+
├── tsconfig.json
|
|
84
|
+
└── vite.config.ts
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### ステップ 1: 依存関係のインストール
|
|
88
|
+
|
|
89
|
+
npm を使用して必要なパッケージをインストールします:
|
|
90
|
+
|
|
91
|
+
```bash packageManager="npm"
|
|
92
|
+
npm install intlayer svelte-intlayer
|
|
93
|
+
npm install vite-intlayer --save-dev
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```bash packageManager="pnpm"
|
|
97
|
+
pnpm add intlayer svelte-intlayer
|
|
98
|
+
pnpm add vite-intlayer --save-dev
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```bash packageManager="yarn"
|
|
102
|
+
yarn add intlayer svelte-intlayer
|
|
103
|
+
yarn add vite-intlayer --save-dev
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```bash packageManager="bun"
|
|
107
|
+
bun add intlayer svelte-intlayer
|
|
108
|
+
bun add vite-intlayer --save-dev
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- **intlayer**: コアのi18nパッケージです。
|
|
112
|
+
- **svelte-intlayer**: Svelte/SvelteKit用のコンテキストプロバイダーとストアを提供します。
|
|
113
|
+
- **vite-intlayer**: コンテンツ宣言をビルドプロセスに統合するためのViteプラグインです。
|
|
114
|
+
|
|
115
|
+
### ステップ 2: プロジェクトの設定
|
|
116
|
+
|
|
117
|
+
プロジェクトのルートに設定ファイルを作成します:
|
|
118
|
+
|
|
119
|
+
```typescript fileName="intlayer.config.ts"
|
|
120
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
121
|
+
|
|
122
|
+
const config: IntlayerConfig = {
|
|
123
|
+
internationalization: {
|
|
124
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
125
|
+
defaultLocale: Locales.ENGLISH,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export default config;
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### ステップ 3: Vite設定にIntlayerを統合する
|
|
133
|
+
|
|
134
|
+
`vite.config.ts`を更新してIntlayerプラグインを含めます。このプラグインはコンテンツファイルのトランスパイルを処理します。
|
|
135
|
+
|
|
136
|
+
```typescript fileName="vite.config.ts"
|
|
137
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
138
|
+
import { defineConfig } from "vite";
|
|
139
|
+
import { intlayer } from "vite-intlayer";
|
|
140
|
+
|
|
141
|
+
export default defineConfig({
|
|
142
|
+
plugins: [intlayer(), sveltekit()], // 順序が重要です。IntlayerはSvelteKitの前に配置してください
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### ステップ4: コンテンツの宣言
|
|
147
|
+
|
|
148
|
+
`src`フォルダ内の任意の場所(例: `src/lib/content` やコンポーネントと同じ場所)にコンテンツ宣言ファイルを作成します。これらのファイルは、各ロケールごとに `t()` 関数を使用してアプリケーションの翻訳可能なコンテンツを定義します。
|
|
149
|
+
|
|
150
|
+
```ts fileName="src/features/hero/hero.content.ts" contentDeclarationFormat="typescript"
|
|
151
|
+
import { t, type Dictionary } from "intlayer";
|
|
152
|
+
|
|
153
|
+
const heroContent = {
|
|
154
|
+
key: "hero-section",
|
|
155
|
+
content: {
|
|
156
|
+
title: t({
|
|
157
|
+
en: "Welcome to SvelteKit",
|
|
158
|
+
fr: "Bienvenue sur SvelteKit",
|
|
159
|
+
es: "Bienvenido a SvelteKit",
|
|
160
|
+
}),
|
|
161
|
+
},
|
|
162
|
+
} satisfies Dictionary;
|
|
163
|
+
|
|
164
|
+
export default heroContent;
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### ステップ5: コンポーネントでIntlayerを利用する
|
|
168
|
+
|
|
169
|
+
今や、任意のSvelteコンポーネント内で`useIntlayer`関数を使用できます。この関数はリアクティブなストアを返し、ロケールが変更されると自動的に更新されます。関数は現在のロケールを自動的に尊重します(SSRおよびクライアントサイドのナビゲーションの両方で)。
|
|
170
|
+
|
|
171
|
+
> **注意:** `useIntlayer`はSvelteのストアを返すため、そのリアクティブな値にアクセスするには`---
|
|
172
|
+
> createdAt: 2025-11-20
|
|
173
|
+
> updatedAt: 2025-11-20
|
|
174
|
+
> title: SvelteKitアプリを翻訳する方法 – i18nガイド 2025
|
|
175
|
+
> description: SvelteKitのウェブサイトを多言語対応にする方法を紹介します。Server-Side Rendering(SSR)を使って国際化(i18n)および翻訳を行うためのドキュメントに従ってください。
|
|
176
|
+
> keywords:
|
|
177
|
+
|
|
178
|
+
- 国際化
|
|
179
|
+
- ドキュメント
|
|
180
|
+
- Intlayer
|
|
181
|
+
- SvelteKit
|
|
182
|
+
- JavaScript
|
|
183
|
+
- SSR
|
|
184
|
+
slugs:
|
|
185
|
+
- doc
|
|
186
|
+
- environment
|
|
187
|
+
- sveltekit
|
|
188
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-sveltekit-template
|
|
189
|
+
history:
|
|
190
|
+
- version: 7.1.10
|
|
191
|
+
date: 2025-11-20
|
|
192
|
+
changes: 初期履歴
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
# Intlayerを使ってSvelteKitのウェブサイトを翻訳する | 国際化(i18n)
|
|
197
|
+
|
|
198
|
+
## 目次
|
|
199
|
+
|
|
200
|
+
<TOC/>
|
|
201
|
+
|
|
202
|
+
## Intlayerとは何ですか?
|
|
203
|
+
|
|
204
|
+
**Intlayer**は、モダンなウェブアプリケーションにおける多言語対応を簡素化するために設計された革新的なオープンソースの国際化(i18n)ライブラリです。**SvelteKit**のサーバーサイドレンダリング(SSR)機能とシームレスに連携します。
|
|
205
|
+
|
|
206
|
+
Intlayerを使うことで、以下が可能になります:
|
|
207
|
+
|
|
208
|
+
- **コンポーネントレベルで宣言的な辞書を使い、翻訳を簡単に管理**できます。
|
|
209
|
+
- **メタデータ、ルート、コンテンツを動的にローカライズ**できます。
|
|
210
|
+
- **自動生成される型情報でTypeScriptのサポートを保証**します。
|
|
211
|
+
- **SvelteKitのSSRを活用してSEOに優しい国際化を実現**します。
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## SvelteKitアプリケーションでIntlayerをセットアップするステップバイステップガイド
|
|
216
|
+
|
|
217
|
+
まずは新しいSvelteKitプロジェクトを作成しましょう。以下は最終的に作成する構成です:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
.
|
|
221
|
+
├── intlayer.config.ts
|
|
222
|
+
├── package.json
|
|
223
|
+
├── src
|
|
224
|
+
│ ├── app.d.ts
|
|
225
|
+
│ ├── app.html
|
|
226
|
+
│ ├── hooks.server.ts
|
|
227
|
+
│ ├── lib
|
|
228
|
+
│ │ ├── getLocale.ts
|
|
229
|
+
│ │ ├── LocaleSwitcher.svelte
|
|
230
|
+
│ │ └── LocalizedLink.svelte
|
|
231
|
+
│ ├── params
|
|
232
|
+
│ │ └── locale.ts
|
|
233
|
+
│ └── routes
|
|
234
|
+
│ ├── [[locale=locale]]
|
|
235
|
+
│ │ ├── +layout.svelte
|
|
236
|
+
│ │ ├── +layout.ts
|
|
237
|
+
│ │ ├── +page.svelte
|
|
238
|
+
│ │ ├── +page.ts
|
|
239
|
+
│ │ ├── about
|
|
240
|
+
│ │ │ ├── +page.svelte
|
|
241
|
+
│ │ │ ├── +page.ts
|
|
242
|
+
│ │ │ └── page.content.ts
|
|
243
|
+
│ │ ├── Counter.content.ts
|
|
244
|
+
│ │ ├── Counter.svelte
|
|
245
|
+
│ │ ├── Header.content.ts
|
|
246
|
+
│ │ ├── Header.svelte
|
|
247
|
+
│ │ ├── home.content.ts
|
|
248
|
+
│ │ └── layout.content.ts
|
|
249
|
+
│ ├── +layout.svelte
|
|
250
|
+
│ └── layout.css
|
|
251
|
+
├── static
|
|
252
|
+
│ ├── favicon.svg
|
|
253
|
+
│ └── robots.txt
|
|
254
|
+
├── svelte.config.js
|
|
255
|
+
├── tsconfig.json
|
|
256
|
+
└── vite.config.ts
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### ステップ 1: 依存関係のインストール
|
|
260
|
+
|
|
261
|
+
npm を使用して必要なパッケージをインストールします:
|
|
262
|
+
|
|
263
|
+
```bash packageManager="npm"
|
|
264
|
+
npm install intlayer svelte-intlayer
|
|
265
|
+
npm install vite-intlayer --save-dev
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
```bash packageManager="pnpm"
|
|
269
|
+
pnpm add intlayer svelte-intlayer
|
|
270
|
+
pnpm add vite-intlayer --save-dev
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
```bash packageManager="yarn"
|
|
274
|
+
yarn add intlayer svelte-intlayer
|
|
275
|
+
yarn add vite-intlayer --save-dev
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
```bash packageManager="bun"
|
|
279
|
+
bun add intlayer svelte-intlayer
|
|
280
|
+
bun add vite-intlayer --save-dev
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
- **intlayer**: コアのi18nパッケージです。
|
|
284
|
+
- **svelte-intlayer**: Svelte/SvelteKit用のコンテキストプロバイダーとストアを提供します。
|
|
285
|
+
- **vite-intlayer**: コンテンツ宣言をビルドプロセスに統合するためのViteプラグインです。
|
|
286
|
+
|
|
287
|
+
### ステップ 2: プロジェクトの設定
|
|
288
|
+
|
|
289
|
+
プロジェクトのルートに設定ファイルを作成します:
|
|
290
|
+
|
|
291
|
+
```typescript fileName="intlayer.config.ts"
|
|
292
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
293
|
+
|
|
294
|
+
const config: IntlayerConfig = {
|
|
295
|
+
internationalization: {
|
|
296
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
297
|
+
defaultLocale: Locales.ENGLISH,
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
export default config;
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### ステップ 3: Vite設定にIntlayerを統合する
|
|
305
|
+
|
|
306
|
+
`vite.config.ts`を更新してIntlayerプラグインを含めます。このプラグインはコンテンツファイルのトランスパイルを処理します。
|
|
307
|
+
|
|
308
|
+
```typescript fileName="vite.config.ts"
|
|
309
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
310
|
+
import { defineConfig } from "vite";
|
|
311
|
+
import { intlayer } from "vite-intlayer";
|
|
312
|
+
|
|
313
|
+
export default defineConfig({
|
|
314
|
+
plugins: [intlayer(), sveltekit()], // 順序が重要です。IntlayerはSvelteKitの前に配置してください
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### ステップ4: コンテンツの宣言
|
|
319
|
+
|
|
320
|
+
`src`フォルダ内の任意の場所(例: `src/lib/content` やコンポーネントと同じ場所)にコンテンツ宣言ファイルを作成します。これらのファイルは、各ロケールごとに `t()` 関数を使用してアプリケーションの翻訳可能なコンテンツを定義します。
|
|
321
|
+
|
|
322
|
+
```ts fileName="src/features/hero/hero.content.ts" contentDeclarationFormat="typescript"
|
|
323
|
+
import { t, type Dictionary } from "intlayer";
|
|
324
|
+
|
|
325
|
+
const heroContent = {
|
|
326
|
+
key: "hero-section",
|
|
327
|
+
content: {
|
|
328
|
+
title: t({
|
|
329
|
+
en: "Welcome to SvelteKit",
|
|
330
|
+
fr: "Bienvenue sur SvelteKit",
|
|
331
|
+
es: "Bienvenido a SvelteKit",
|
|
332
|
+
}),
|
|
333
|
+
},
|
|
334
|
+
} satisfies Dictionary;
|
|
335
|
+
|
|
336
|
+
export default heroContent;
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### ステップ5: コンポーネントでIntlayerを利用する
|
|
340
|
+
|
|
341
|
+
プレフィックスを使用する必要があります(例:`$content.title`)。
|
|
342
|
+
|
|
343
|
+
```svelte fileName="src/lib/components/Component.svelte"
|
|
344
|
+
<script lang="ts">
|
|
345
|
+
import { useIntlayer } from "svelte-intlayer";
|
|
346
|
+
|
|
347
|
+
// "hero-section"はステップ4で定義したキーに対応します
|
|
348
|
+
const content = useIntlayer("hero-section");
|
|
349
|
+
</script>
|
|
350
|
+
|
|
351
|
+
<!-- コンテンツを単純にレンダリング -->
|
|
352
|
+
<h1>{$content.title}</h1>
|
|
353
|
+
<!-- エディターを使って編集可能なコンテンツとしてレンダリング -->
|
|
354
|
+
<h1><svelte:component this={$content.title} /></h1>
|
|
355
|
+
<!-- コンテンツを文字列としてレンダリングする場合 -->
|
|
356
|
+
<div aria-label={$content.title.value}></div>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### (オプション)ステップ6: ルーティングの設定
|
|
360
|
+
|
|
361
|
+
以下の手順では、SvelteKitでロケールベースのルーティングを設定する方法を示します。これにより、URLにロケールのプレフィックス(例:`/en/about`、`/fr/about`)を含めることができ、SEOやユーザー体験が向上します。
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
.
|
|
365
|
+
└─── src
|
|
366
|
+
├── app.d.ts # ロケールタイプを定義
|
|
367
|
+
├── hooks.server.ts # ロケールルーティングを管理
|
|
368
|
+
├── lib
|
|
369
|
+
│ └── getLocale.ts # ヘッダーやクッキーからロケールをチェック
|
|
370
|
+
├── params
|
|
371
|
+
│ └── locale.ts # ロケールパラメータを定義
|
|
372
|
+
└── routes
|
|
373
|
+
├── [[locale=locale]] # ルートグループでロケールを設定するためにラップ
|
|
374
|
+
│ ├── +layout.svelte # ルートのローカルレイアウト
|
|
375
|
+
│ ├── +layout.ts
|
|
376
|
+
│ ├── +page.svelte
|
|
377
|
+
│ ├── +page.ts
|
|
378
|
+
│ └── about
|
|
379
|
+
│ ├── +page.svelte
|
|
380
|
+
│ └── +page.ts
|
|
381
|
+
└── +layout.svelte # フォントとグローバルスタイルのためのルートレイアウト
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### ステップ7: サーバーサイドのロケール検出を処理する(Hooks)
|
|
385
|
+
|
|
386
|
+
SvelteKitでは、SSR中に正しいコンテンツをレンダリングするためにサーバーがユーザーのロケールを知る必要があります。`hooks.server.ts`を使ってURLやクッキーからロケールを検出します。
|
|
387
|
+
|
|
388
|
+
`src/hooks.server.ts`を作成または修正してください:
|
|
389
|
+
|
|
390
|
+
```typescript fileName="src/hooks.server.ts"
|
|
391
|
+
import type { Handle } from "@sveltejs/kit";
|
|
392
|
+
import { getLocalizedUrl } from "intlayer";
|
|
393
|
+
import { getLocale } from "$lib/getLocale";
|
|
394
|
+
|
|
395
|
+
export const handle: Handle = async ({ event, resolve }) => {
|
|
396
|
+
const detectedLocale = getLocale(event);
|
|
397
|
+
|
|
398
|
+
// 現在のパスがすでにロケールで始まっているかを確認(例: /fr, /en)
|
|
399
|
+
const pathname = event.url.pathname;
|
|
400
|
+
const targetPathname = getLocalizedUrl(pathname, detectedLocale);
|
|
401
|
+
|
|
402
|
+
// URLにロケールが含まれていない場合(例: ユーザーが "/" にアクセスした場合)、リダイレクトする
|
|
403
|
+
if (targetPathname !== pathname) {
|
|
404
|
+
return new Response(undefined, {
|
|
405
|
+
headers: { Location: targetPathname },
|
|
406
|
+
status: 307, // 一時的なリダイレクト
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return resolve(event, {
|
|
411
|
+
transformPageChunk: ({ html }) => html.replace("%lang%", detectedLocale),
|
|
412
|
+
});
|
|
413
|
+
};
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
次に、リクエストイベントからユーザーのロケールを取得するヘルパーを作成します:
|
|
417
|
+
|
|
418
|
+
```typescript fileName="src/lib/getLocale.ts"
|
|
419
|
+
import {
|
|
420
|
+
configuration,
|
|
421
|
+
getLocaleFromStorage,
|
|
422
|
+
localeDetector,
|
|
423
|
+
type Locale,
|
|
424
|
+
} from "intlayer";
|
|
425
|
+
import type { RequestEvent } from "@sveltejs/kit";
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* リクエストイベントからユーザーのロケールを取得します。
|
|
429
|
+
* この関数は `src/hooks.server.ts` の `handle` フックで使用されます。
|
|
430
|
+
*
|
|
431
|
+
* まず、Intlayerのストレージ(クッキーまたはカスタムヘッダー)からロケールを取得しようとします。
|
|
432
|
+
* ロケールが見つからない場合は、ブラウザの "Accept-Language" ネゴシエーションにフォールバックします。
|
|
433
|
+
*
|
|
434
|
+
* @param event - SvelteKitからのリクエストイベント
|
|
435
|
+
* @returns ユーザーのロケール
|
|
436
|
+
*/
|
|
437
|
+
export const getLocale = (event: RequestEvent): Locale => {
|
|
438
|
+
const defaultLocale = configuration?.internationalization?.defaultLocale;
|
|
439
|
+
|
|
440
|
+
// Intlayerのストレージ(クッキーまたはヘッダー)からロケールを取得しようとする
|
|
441
|
+
const storedLocale = getLocaleFromStorage({
|
|
442
|
+
// SvelteKitのクッキーアクセス
|
|
443
|
+
getCookie: (name: string) => event.cookies.get(name) ?? null,
|
|
444
|
+
// SvelteKitのヘッダーアクセス
|
|
445
|
+
getHeader: (name: string) => event.request.headers.get(name) ?? null,
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
if (storedLocale) {
|
|
449
|
+
return storedLocale;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// ブラウザの "Accept-Language" ネゴシエーションにフォールバック
|
|
453
|
+
const negotiatorHeaders: Record<string, string> = {};
|
|
454
|
+
|
|
455
|
+
// SvelteKitのHeadersオブジェクトをプレーンなRecord<string, string>に変換
|
|
456
|
+
event.request.headers.forEach((value, key) => {
|
|
457
|
+
negotiatorHeaders[key] = value;
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
// `Accept-Language` ヘッダーからロケールをチェック
|
|
461
|
+
const userFallbackLocale = localeDetector(negotiatorHeaders);
|
|
462
|
+
|
|
463
|
+
if (userFallbackLocale) {
|
|
464
|
+
return userFallbackLocale;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// 一致するものがなければデフォルトのロケールを返す
|
|
468
|
+
return defaultLocale;
|
|
469
|
+
};
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
> `getLocaleFromStorage` は、設定に応じてヘッダーまたはクッキーからロケールをチェックします。詳細は [Configuration](https://intlayer.org/doc/configuration) を参照してください。
|
|
473
|
+
|
|
474
|
+
> `localeDetector` 関数は `Accept-Language` ヘッダーを処理し、最適なマッチを返します。
|
|
475
|
+
|
|
476
|
+
ロケールが設定されていない場合は、404エラーを返したいです。これを簡単にするために、ロケールが有効かどうかをチェックする `match` 関数を作成できます。
|
|
477
|
+
|
|
478
|
+
```ts fileName="/src/params/locale.ts"
|
|
479
|
+
import { configuration, type Locale } from "intlayer";
|
|
480
|
+
|
|
481
|
+
export const match = (
|
|
482
|
+
param: Locale = configuration.internationalization.defaultLocale
|
|
483
|
+
): boolean => {
|
|
484
|
+
return configuration.internationalization.locales.includes(param);
|
|
485
|
+
};
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
> **注意:** `src/app.d.ts` にロケール定義が含まれていることを確認してください:
|
|
489
|
+
>
|
|
490
|
+
> ```typescript
|
|
491
|
+
> declare global {
|
|
492
|
+
> namespace App {
|
|
493
|
+
> interface Locals {
|
|
494
|
+
> locale: import("intlayer").Locale;
|
|
495
|
+
> }
|
|
496
|
+
> }
|
|
497
|
+
> }
|
|
498
|
+
> ```
|
|
499
|
+
|
|
500
|
+
`+layout.svelte` ファイルでは、i18n に関連しない静的コンテンツのみを保持するために、すべての内容を削除できます。
|
|
501
|
+
|
|
502
|
+
```svelte fileName="src/+layout.svelte"
|
|
503
|
+
<script lang="ts">
|
|
504
|
+
import './layout.css';
|
|
505
|
+
|
|
506
|
+
let { children } = $props();
|
|
507
|
+
</script>
|
|
508
|
+
|
|
509
|
+
<div class="app">
|
|
510
|
+
{@render children()}
|
|
511
|
+
</div>
|
|
512
|
+
|
|
513
|
+
<style>
|
|
514
|
+
.app {
|
|
515
|
+
/* */
|
|
516
|
+
}
|
|
517
|
+
</style>
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
次に、`[[locale=locale]]` グループの下に新しいページとレイアウトを作成します。
|
|
521
|
+
|
|
522
|
+
```ts fileName="src/routes/[[locale=locale]]/+layout.ts"
|
|
523
|
+
import type { Load } from "@sveltejs/kit";
|
|
524
|
+
import { configuration, type Locale } from "intlayer";
|
|
525
|
+
|
|
526
|
+
export const prerender = true;
|
|
527
|
+
|
|
528
|
+
// ジェネリックな Load タイプを使用
|
|
529
|
+
export const load: Load = ({ params }) => {
|
|
530
|
+
const locale: Locale =
|
|
531
|
+
(params.locale as Locale) ??
|
|
532
|
+
configuration.internationalization.defaultLocale;
|
|
533
|
+
|
|
534
|
+
return {
|
|
535
|
+
locale,
|
|
536
|
+
};
|
|
537
|
+
};
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
```svelte fileName="src/routes/[[locale=locale]]/+layout.svelte"
|
|
541
|
+
<script lang="ts">
|
|
542
|
+
import type { Snippet } from 'svelte';
|
|
543
|
+
import { useIntlayer, setupIntlayer } from 'svelte-intlayer';
|
|
544
|
+
import Header from './Header.svelte';
|
|
545
|
+
import type { LayoutData } from './$types';
|
|
546
|
+
|
|
547
|
+
let { children, data }: { children: Snippet, data: LayoutData } = $props();
|
|
548
|
+
|
|
549
|
+
// ルートからのロケールでIntlayerを初期化
|
|
550
|
+
setupIntlayer(data.locale);
|
|
551
|
+
|
|
552
|
+
// レイアウトのコンテンツ辞書を使用
|
|
553
|
+
const layoutContent = useIntlayer('layout');
|
|
554
|
+
</script>
|
|
555
|
+
|
|
556
|
+
<Header />
|
|
557
|
+
|
|
558
|
+
<main>
|
|
559
|
+
{@render children()}
|
|
560
|
+
</main>
|
|
561
|
+
|
|
562
|
+
<footer>
|
|
563
|
+
<p>
|
|
564
|
+
{$layoutContent.footer.prefix.value}{' '}
|
|
565
|
+
<a href="https://svelte.dev/docs/kit">{$layoutContent.footer.linkLabel.value}</a>{' '}
|
|
566
|
+
{$layoutContent.footer.suffix.value}
|
|
567
|
+
</p>
|
|
568
|
+
</footer>
|
|
569
|
+
|
|
570
|
+
<style>
|
|
571
|
+
/* */
|
|
572
|
+
</style>
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
```ts fileName="src/routes/[[locale=locale]]/+page.ts"
|
|
576
|
+
export const prerender = true;
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
```svelte fileName="src/routes/[[locale=locale]]/+page.svelte"
|
|
580
|
+
<script lang="ts">
|
|
581
|
+
import { useIntlayer } from 'svelte-intlayer';
|
|
582
|
+
|
|
583
|
+
// ホームコンテンツ辞書を使用
|
|
584
|
+
const homeContent = useIntlayer('home');
|
|
585
|
+
</script>
|
|
586
|
+
|
|
587
|
+
<svelte:head>
|
|
588
|
+
<title>{$homeContent.title.value}</title>
|
|
589
|
+
</svelte:head>
|
|
590
|
+
|
|
591
|
+
<section>
|
|
592
|
+
<h1>
|
|
593
|
+
{$homeContent.title}
|
|
594
|
+
</h1>
|
|
595
|
+
</section>
|
|
596
|
+
|
|
597
|
+
<style>
|
|
598
|
+
/* */
|
|
599
|
+
</style>
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### (オプション)ステップ8:国際化されたリンク
|
|
603
|
+
|
|
604
|
+
SEOのために、ルートにロケールをプレフィックスとして付けることを推奨します(例:`/en/about`、`/fr/about`)。このコンポーネントは、現在のロケールを自動的にリンクにプレフィックスします。
|
|
605
|
+
|
|
606
|
+
```svelte fileName="src/lib/components/LocalizedLink.svelte"
|
|
607
|
+
<script lang="ts">
|
|
608
|
+
import { getLocalizedUrl } from "intlayer";
|
|
609
|
+
import { useLocale } from 'svelte-intlayer';
|
|
610
|
+
|
|
611
|
+
let { href = "" } = $props();
|
|
612
|
+
const { locale } = useLocale();
|
|
613
|
+
|
|
614
|
+
// 現在のロケールでURLにプレフィックスを付けるヘルパー
|
|
615
|
+
$: localizedHref = getLocalizedUrl(href, $locale);
|
|
616
|
+
</script>
|
|
617
|
+
|
|
618
|
+
<a href={localizedHref}>
|
|
619
|
+
<slot />
|
|
620
|
+
</a>
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
SvelteKitの`goto`を使用する場合も、同じロジックを`getLocalizedUrl`で使ってローカライズされたURLにナビゲートできます:
|
|
624
|
+
|
|
625
|
+
```typescript
|
|
626
|
+
import { goto } from "$app/navigation";
|
|
627
|
+
import { getLocalizedUrl } from "intlayer";
|
|
628
|
+
import { useLocale } from "svelte-intlayer";
|
|
629
|
+
|
|
630
|
+
const { locale } = useLocale();
|
|
631
|
+
const localizedPath = getLocalizedUrl("/about", $locale);
|
|
632
|
+
goto(localizedPath); // ロケールに応じて /en/about または /fr/about に遷移します
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
### (オプション)ステップ9: 言語切り替えコンポーネント
|
|
636
|
+
|
|
637
|
+
ユーザーが言語を切り替えられるように、URLを更新します。
|
|
638
|
+
|
|
639
|
+
```svelte fileName="src/lib/components/LanguageSwitcher.svelte"
|
|
640
|
+
<script lang="ts">
|
|
641
|
+
import { getLocalizedUrl, getLocaleName } from 'intlayer';
|
|
642
|
+
import { useLocale } from 'svelte-intlayer';
|
|
643
|
+
import { page } from '$app/stores';
|
|
644
|
+
import { goto } from '$app/navigation';
|
|
645
|
+
|
|
646
|
+
const { locale, setLocale, availableLocales } = useLocale({
|
|
647
|
+
onLocaleChange: (newLocale) => {
|
|
648
|
+
const localizedPath = getLocalizedUrl($page.url.pathname, newLocale);
|
|
649
|
+
goto(localizedPath);
|
|
650
|
+
},
|
|
651
|
+
});
|
|
652
|
+
</script>
|
|
653
|
+
|
|
654
|
+
<ul class="locale-list">
|
|
655
|
+
{#each availableLocales as localeEl}
|
|
656
|
+
<li>
|
|
657
|
+
<a
|
|
658
|
+
href={getLocalizedUrl($page.url.pathname, localeEl)}
|
|
659
|
+
onclick={(e) => {
|
|
660
|
+
e.preventDefault();
|
|
661
|
+
setLocale(localeEl); // ストア内のロケールを設定し、onLocaleChangeをトリガーします
|
|
662
|
+
}}
|
|
663
|
+
class:active={$locale === localeEl}
|
|
664
|
+
>
|
|
665
|
+
{getLocaleName(localeEl)}
|
|
666
|
+
</a>
|
|
667
|
+
</li>
|
|
668
|
+
{/each}
|
|
669
|
+
</ul>
|
|
670
|
+
|
|
671
|
+
<style>
|
|
672
|
+
/* */
|
|
673
|
+
</style>
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
### (オプション)ステップ10:バックエンドプロキシの追加
|
|
677
|
+
|
|
678
|
+
SvelteKitアプリケーションにバックエンドプロキシを追加するには、`vite-intlayer`プラグインが提供する`intlayerProxy`関数を使用できます。このプラグインは、URL、クッキー、およびブラウザの言語設定に基づいてユーザーに最適なロケールを自動的に検出します。
|
|
679
|
+
|
|
680
|
+
```ts fileName="vite.config.ts"
|
|
681
|
+
import { defineConfig } from "vite";
|
|
682
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
683
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
684
|
+
|
|
685
|
+
// https://vitejs.dev/config/
|
|
686
|
+
export default defineConfig({
|
|
687
|
+
plugins: [intlayer(), intlayerProxy(), sveltekit()],
|
|
688
|
+
});
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
### (オプション)ステップ11:intlayerエディター / CMSのセットアップ
|
|
692
|
+
|
|
693
|
+
intlayerエディターをセットアップするには、[intlayerエディターのドキュメント](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/intlayer_visual_editor.md)に従う必要があります。
|
|
694
|
+
|
|
695
|
+
intlayer CMSをセットアップするには、[intlayer CMSのドキュメント](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/intlayer_CMS.md)に従う必要があります。
|
|
696
|
+
|
|
697
|
+
intlayerエディターのセレクターを可視化するためには、intlayerコンテンツ内でコンポーネント構文を使用する必要があります。
|
|
698
|
+
|
|
699
|
+
```svelte fileName="Component.svelte"
|
|
700
|
+
<script lang="ts">
|
|
701
|
+
import { useIntlayer } from "svelte-intlayer";
|
|
702
|
+
|
|
703
|
+
const content = useIntlayer("component");
|
|
704
|
+
</script>
|
|
705
|
+
|
|
706
|
+
<div>
|
|
707
|
+
|
|
708
|
+
<!-- コンテンツをシンプルな内容としてレンダリング -->
|
|
709
|
+
<h1>{$content.title}</h1>
|
|
710
|
+
|
|
711
|
+
<!-- コンポーネントとしてコンテンツをレンダリング(エディターに必要) -->
|
|
712
|
+
<svelte:component this={$content.component} />
|
|
713
|
+
</div>
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### Git設定
|
|
717
|
+
|
|
718
|
+
Intlayerによって生成されるファイルは無視することを推奨します。
|
|
719
|
+
|
|
720
|
+
```plaintext fileName=".gitignore"
|
|
721
|
+
# Intlayerによって生成されたファイルを無視
|
|
722
|
+
.intlayer
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
---
|
|
726
|
+
|
|
727
|
+
### さらに進む
|
|
728
|
+
|
|
729
|
+
- **ビジュアルエディター**: UIから直接翻訳を編集するために、[Intlayer Visual Editor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/intlayer_visual_editor.md)を統合します。
|
|
730
|
+
- **CMS**: コンテンツ管理を外部化するために、[Intlayer CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/intlayer_CMS.md)を使用します。
|