@intlayer/docs 5.7.6-canary.0 → 5.7.7
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/generated/docs.entry.cjs +44 -238
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +44 -238
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -2
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/intlayer_with_tanstack.md +457 -0
- package/docs/ar/packages/next-intlayer/index.md +0 -1
- package/docs/ar/packages/react-intlayer/index.md +0 -1
- package/docs/de/intlayer_with_tanstack.md +458 -0
- package/docs/de/packages/next-intlayer/index.md +0 -1
- package/docs/de/packages/react-intlayer/index.md +0 -1
- package/docs/en/intlayer_with_tanstack.md +452 -0
- package/docs/en/packages/next-intlayer/index.md +0 -1
- package/docs/en/packages/react-intlayer/index.md +0 -1
- package/docs/en-GB/intlayer_with_tanstack.md +457 -0
- package/docs/en-GB/packages/next-intlayer/index.md +0 -1
- package/docs/en-GB/packages/react-intlayer/index.md +0 -1
- package/docs/es/intlayer_with_tanstack.md +435 -0
- package/docs/es/packages/next-intlayer/index.md +0 -1
- package/docs/es/packages/react-intlayer/index.md +0 -1
- package/docs/fr/intlayer_with_tanstack.md +435 -0
- package/docs/fr/packages/next-intlayer/index.md +0 -1
- package/docs/fr/packages/react-intlayer/index.md +0 -1
- package/docs/hi/intlayer_with_tanstack.md +438 -0
- package/docs/hi/packages/next-intlayer/index.md +0 -1
- package/docs/hi/packages/react-intlayer/index.md +0 -1
- package/docs/it/intlayer_with_tanstack.md +457 -0
- package/docs/it/packages/next-intlayer/index.md +0 -1
- package/docs/it/packages/react-intlayer/index.md +0 -1
- package/docs/ja/intlayer_with_tanstack.md +457 -0
- package/docs/ja/packages/next-intlayer/index.md +0 -1
- package/docs/ja/packages/react-intlayer/index.md +0 -1
- package/docs/ko/intlayer_with_tanstack.md +457 -0
- package/docs/ko/packages/next-intlayer/index.md +0 -1
- package/docs/ko/packages/react-intlayer/index.md +0 -1
- package/docs/pt/intlayer_with_tanstack.md +457 -0
- package/docs/pt/packages/next-intlayer/index.md +0 -1
- package/docs/pt/packages/react-intlayer/index.md +0 -1
- package/docs/ru/intlayer_with_tanstack.md +458 -0
- package/docs/ru/packages/next-intlayer/index.md +0 -1
- package/docs/ru/packages/react-intlayer/index.md +0 -1
- package/docs/zh/intlayer_with_tanstack.md +435 -0
- package/docs/zh/packages/next-intlayer/index.md +0 -1
- package/docs/zh/packages/react-intlayer/index.md +0 -1
- package/package.json +8 -8
- package/src/generated/docs.entry.ts +44 -238
- package/docs/ar/packages/next-intlayer/useIntlayerAsync.md +0 -237
- package/docs/ar/packages/react-intlayer/useIntlayerAsync.md +0 -252
- package/docs/de/packages/next-intlayer/useIntlayerAsync.md +0 -262
- package/docs/de/packages/react-intlayer/useIntlayerAsync.md +0 -256
- package/docs/en/packages/next-intlayer/useIntlayerAsync.md +0 -239
- package/docs/en/packages/react-intlayer/useIntlayerAsync.md +0 -254
- package/docs/en-GB/packages/next-intlayer/useIntlayerAsync.md +0 -237
- package/docs/en-GB/packages/react-intlayer/useIntlayerAsync.md +0 -257
- package/docs/es/packages/next-intlayer/useIntlayerAsync.md +0 -240
- package/docs/es/packages/react-intlayer/useIntlayerAsync.md +0 -276
- package/docs/fr/packages/next-intlayer/useIntlayerAsync.md +0 -238
- package/docs/fr/packages/react-intlayer/useIntlayerAsync.md +0 -252
- package/docs/hi/packages/next-intlayer/useIntlayerAsync.md +0 -237
- package/docs/hi/packages/react-intlayer/useIntlayerAsync.md +0 -252
- package/docs/it/packages/next-intlayer/useIntlayerAsync.md +0 -237
- package/docs/it/packages/react-intlayer/useIntlayerAsync.md +0 -252
- package/docs/ja/packages/next-intlayer/useIntlayerAsync.md +0 -237
- package/docs/ja/packages/react-intlayer/useIntlayerAsync.md +0 -268
- package/docs/ko/packages/next-intlayer/useIntlayerAsync.md +0 -260
- package/docs/ko/packages/react-intlayer/useIntlayerAsync.md +0 -271
- package/docs/pt/packages/next-intlayer/useIntlayerAsync.md +0 -238
- package/docs/pt/packages/react-intlayer/useIntlayerAsync.md +0 -252
- package/docs/ru/packages/next-intlayer/useIntlayerAsync.md +0 -237
- package/docs/ru/packages/react-intlayer/useIntlayerAsync.md +0 -252
- package/docs/zh/packages/next-intlayer/useIntlayerAsync.md +0 -239
- package/docs/zh/packages/react-intlayer/useIntlayerAsync.md +0 -257
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-08-11
|
|
3
|
+
updatedAt: 2025-08-11
|
|
4
|
+
title: Начало работы с Intlayer в TanStack Start (React)
|
|
5
|
+
description: Добавьте i18n в ваше приложение TanStack Start с помощью Intlayer — словари на уровне компонентов, локализованные URL и SEO-дружественные метаданные.
|
|
6
|
+
keywords:
|
|
7
|
+
- Интернационализация
|
|
8
|
+
- Документация
|
|
9
|
+
- Intlayer
|
|
10
|
+
- TanStack Start
|
|
11
|
+
- TanStack Router
|
|
12
|
+
- React
|
|
13
|
+
- i18n
|
|
14
|
+
- JavaScript
|
|
15
|
+
slugs:
|
|
16
|
+
- doc
|
|
17
|
+
- environment
|
|
18
|
+
- tanstack-start
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Начало работы с интернационализацией (i18n) с Intlayer и TanStack Start (React)
|
|
22
|
+
|
|
23
|
+
## Что такое Intlayer?
|
|
24
|
+
|
|
25
|
+
**Intlayer** — это открытый набор инструментов i18n для приложений React. Он предоставляет вам:
|
|
26
|
+
|
|
27
|
+
- **Словари на уровне компонентов** с безопасностью TypeScript.
|
|
28
|
+
- **Динамические метаданные и маршруты** (готовые для SEO).
|
|
29
|
+
- **Переключение локали во время выполнения** (и вспомогательные функции для обнаружения/сохранения локалей).
|
|
30
|
+
- **Плагин Vite** для преобразований во время сборки + улучшения для разработки (DX).
|
|
31
|
+
|
|
32
|
+
В этом руководстве показано, как интегрировать Intlayer в проект **TanStack Start** (который использует Vite под капотом и TanStack Router для маршрутизации/SSR).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Шаг 1: Установка зависимостей
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# npm
|
|
40
|
+
npm i intlayer react-intlayer
|
|
41
|
+
npm i -D vite-intlayer
|
|
42
|
+
|
|
43
|
+
# pnpm
|
|
44
|
+
pnpm add intlayer react-intlayer
|
|
45
|
+
pnpm add -D vite-intlayer
|
|
46
|
+
|
|
47
|
+
# yarn
|
|
48
|
+
yarn add intlayer react-intlayer
|
|
49
|
+
yarn add -D vite-intlayer
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
- **intlayer**: ядро (конфигурация, словари, CLI/преобразования).
|
|
53
|
+
- **react-intlayer**: `<IntlayerProvider>` + хуки для React.
|
|
54
|
+
- **vite-intlayer**: плагин Vite, а также опциональное промежуточное ПО для обнаружения локали/перенаправлений (работает в режиме разработки и SSR/превью; для production SSR переместите в `dependencies`).
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Шаг 2: Настройка Intlayer
|
|
59
|
+
|
|
60
|
+
Создайте файл `intlayer.config.ts` в корне вашего проекта:
|
|
61
|
+
|
|
62
|
+
```ts fileName="intlayer.config.ts"
|
|
63
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
64
|
+
|
|
65
|
+
const config: IntlayerConfig = {
|
|
66
|
+
internationalization: {
|
|
67
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
68
|
+
defaultLocale: Locales.ENGLISH,
|
|
69
|
+
},
|
|
70
|
+
// Вы также можете настроить: contentDir, contentFileExtensions, параметры middleware и др.
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default config;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Варианты CommonJS/ESM идентичны вашему оригинальному документу, если вы предпочитаете `cjs`/`mjs`.
|
|
77
|
+
|
|
78
|
+
> Полное описание конфигурации: смотрите документацию по конфигурации Intlayer.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Шаг 3: Добавьте плагин Vite (и опциональный middleware)
|
|
83
|
+
|
|
84
|
+
**TanStack Start использует Vite**, поэтому добавьте плагин(и) Intlayer в ваш `vite.config.ts`:
|
|
85
|
+
|
|
86
|
+
```ts fileName="vite.config.ts"
|
|
87
|
+
import { defineConfig } from "vite";
|
|
88
|
+
import react from "@vitejs/plugin-react-swc";
|
|
89
|
+
import { intlayerPlugin, intLayerMiddlewarePlugin } from "vite-intlayer";
|
|
90
|
+
|
|
91
|
+
export default defineConfig({
|
|
92
|
+
plugins: [
|
|
93
|
+
react(),
|
|
94
|
+
intlayerPlugin(),
|
|
95
|
+
// Необязательно, но рекомендуется для обнаружения локали, работы с куки и редиректов:
|
|
96
|
+
intLayerMiddlewarePlugin(),
|
|
97
|
+
],
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
> Если вы разворачиваете SSR, переместите `vite-intlayer` в `dependencies`, чтобы middleware работал в продакшене.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Шаг 4: Объявите ваш контент
|
|
106
|
+
|
|
107
|
+
Размещайте ваши словари где угодно внутри `./src` (по умолчанию `contentDir`). Пример:
|
|
108
|
+
|
|
109
|
+
```tsx fileName="src/app.content.tsx"
|
|
110
|
+
import { t, type Dictionary } from "intlayer";
|
|
111
|
+
import type { ReactNode } from "react";
|
|
112
|
+
|
|
113
|
+
const appContent = {
|
|
114
|
+
key: "app",
|
|
115
|
+
content: {
|
|
116
|
+
viteLogo: t({
|
|
117
|
+
ru: "Логотип Vite",
|
|
118
|
+
en: "Vite logo",
|
|
119
|
+
fr: "Logo Vite",
|
|
120
|
+
es: "Logo Vite",
|
|
121
|
+
}),
|
|
122
|
+
reactLogo: t({
|
|
123
|
+
ru: "Логотип React",
|
|
124
|
+
en: "React logo",
|
|
125
|
+
fr: "Logo React",
|
|
126
|
+
es: "Logo React",
|
|
127
|
+
}),
|
|
128
|
+
title: t({
|
|
129
|
+
ru: "TanStack Start + React",
|
|
130
|
+
en: "TanStack Start + React",
|
|
131
|
+
fr: "TanStack Start + React",
|
|
132
|
+
es: "TanStack Start + React",
|
|
133
|
+
}),
|
|
134
|
+
count: t({
|
|
135
|
+
ru: "счёт: ",
|
|
136
|
+
en: "count is ",
|
|
137
|
+
fr: "le compte est ",
|
|
138
|
+
es: "el recuento es ",
|
|
139
|
+
}),
|
|
140
|
+
edit: t<ReactNode>({
|
|
141
|
+
ru: (
|
|
142
|
+
<>
|
|
143
|
+
Редактируйте <code>src/routes/index.tsx</code> и сохраните, чтобы
|
|
144
|
+
проверить HMR
|
|
145
|
+
</>
|
|
146
|
+
),
|
|
147
|
+
en: (
|
|
148
|
+
<>
|
|
149
|
+
Edit <code>src/routes/index.tsx</code> and save to test HMR
|
|
150
|
+
</>
|
|
151
|
+
),
|
|
152
|
+
fr: (
|
|
153
|
+
<>
|
|
154
|
+
Éditez <code>src/routes/index.tsx</code> et enregistrez pour tester
|
|
155
|
+
HMR
|
|
156
|
+
</>
|
|
157
|
+
),
|
|
158
|
+
es: (
|
|
159
|
+
<>
|
|
160
|
+
Edita <code>src/routes/index.tsx</code> y guarda para probar HMR
|
|
161
|
+
</>
|
|
162
|
+
),
|
|
163
|
+
}),
|
|
164
|
+
readTheDocs: t({
|
|
165
|
+
ru: "Нажмите на логотипы, чтобы узнать больше",
|
|
166
|
+
en: "Click the logos to learn more",
|
|
167
|
+
fr: "Cliquez sur les logos pour en savoir plus",
|
|
168
|
+
es: "Haz clic en los logotipos para saber más",
|
|
169
|
+
}),
|
|
170
|
+
},
|
|
171
|
+
} satisfies Dictionary;
|
|
172
|
+
|
|
173
|
+
export default appContent;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
JSON/ESM/CJS варианты работают так же, как и в вашем исходном документе.
|
|
177
|
+
|
|
178
|
+
> TSX контент? Не забудьте `import React from "react"`, если ваша сборка этого требует.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Шаг 5: Оберните TanStack Start с помощью Intlayer
|
|
183
|
+
|
|
184
|
+
С TanStack Start ваш **корневой маршрут** — это правильное место для установки провайдеров.
|
|
185
|
+
|
|
186
|
+
```tsx fileName="src/routes/__root.tsx"
|
|
187
|
+
import {
|
|
188
|
+
Outlet,
|
|
189
|
+
createRootRoute,
|
|
190
|
+
Link as RouterLink,
|
|
191
|
+
} from "@tanstack/react-router";
|
|
192
|
+
import { IntlayerProvider, useIntlayer } from "react-intlayer";
|
|
193
|
+
|
|
194
|
+
function AppShell() {
|
|
195
|
+
// Пример использования словаря на верхнем уровне:
|
|
196
|
+
const content = useIntlayer("app");
|
|
197
|
+
|
|
198
|
+
return (
|
|
199
|
+
<div>
|
|
200
|
+
<nav className="flex gap-3 p-3">
|
|
201
|
+
<RouterLink to="/">Главная</RouterLink>
|
|
202
|
+
<RouterLink to="/about">О нас</RouterLink>
|
|
203
|
+
</nav>
|
|
204
|
+
<main className="p-6">
|
|
205
|
+
<h1>{content.title}</h1>
|
|
206
|
+
<Outlet />
|
|
207
|
+
</main>
|
|
208
|
+
</div>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export const Route = createRootRoute({
|
|
213
|
+
component: () => (
|
|
214
|
+
<IntlayerProvider>
|
|
215
|
+
<AppShell />
|
|
216
|
+
</IntlayerProvider>
|
|
217
|
+
),
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Затем используйте ваш контент на страницах:
|
|
222
|
+
|
|
223
|
+
```tsx fileName="src/routes/index.tsx"
|
|
224
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
225
|
+
import { useIntlayer } from "react-intlayer";
|
|
226
|
+
import reactLogo from "../assets/react.svg";
|
|
227
|
+
|
|
228
|
+
export const Route = createFileRoute("/")({
|
|
229
|
+
component: () => {
|
|
230
|
+
const content = useIntlayer("app");
|
|
231
|
+
return (
|
|
232
|
+
<>
|
|
233
|
+
<button>{content.count}0</button>
|
|
234
|
+
<p>{content.edit}</p>
|
|
235
|
+
<img
|
|
236
|
+
src={reactLogo}
|
|
237
|
+
alt={content.reactLogo.value}
|
|
238
|
+
width={48}
|
|
239
|
+
height={48}
|
|
240
|
+
/>
|
|
241
|
+
<p className="opacity-70">{content.readTheDocs}</p>
|
|
242
|
+
</>
|
|
243
|
+
);
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
> Атрибуты строк (`alt`, `title`, `aria-label` и др.) требуют использования `.value`:
|
|
249
|
+
>
|
|
250
|
+
> ```jsx
|
|
251
|
+
> <img alt={c.reactLogo.value} />
|
|
252
|
+
> ```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## (Необязательно) Шаг 6: Переключение локали (на клиенте)
|
|
257
|
+
|
|
258
|
+
```tsx fileName="src/components/LocaleSwitcher.tsx"
|
|
259
|
+
import { Locales } from "intlayer";
|
|
260
|
+
import { useLocale } from "react-intlayer";
|
|
261
|
+
|
|
262
|
+
export function LocaleSwitcher() {
|
|
263
|
+
const { setLocale } = useLocale();
|
|
264
|
+
return (
|
|
265
|
+
<div className="flex gap-2">
|
|
266
|
+
<button onClick={() => setLocale(Locales.ENGLISH)}>Английский</button>
|
|
267
|
+
<button onClick={() => setLocale(Locales.FRENCH)}>Французский</button>
|
|
268
|
+
<button onClick={() => setLocale(Locales.SPANISH)}>Испанский</button>
|
|
269
|
+
</div>
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## (Необязательно) Шаг 7: Локализованная маршрутизация (SEO-дружественные URL)
|
|
277
|
+
|
|
278
|
+
У вас есть **два хороших варианта** с TanStack Start. Выберите один.
|
|
279
|
+
|
|
280
|
+
Создайте папку с динамическим сегментом `src/routes/$locale/`, чтобы ваши URL были вида `/:locale/...`. В макете `$locale` проверьте `params.locale`, установите `<IntlayerProvider locale=...>`, и отобразите `<Outlet />`. Этот подход прост, но остальные маршруты будут размещены внутри `$locale`, и вам понадобится дополнительное дерево без префикса, если вы _не_ хотите, чтобы префикс локали по умолчанию добавлялся.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## (Необязательно) Шаг 8: Обновление URL при переключении локали
|
|
285
|
+
|
|
286
|
+
При использовании шаблона A (basepath) переключение локалей означает **переход на другой базовый путь**:
|
|
287
|
+
|
|
288
|
+
```tsx fileName="src/components/LocaleSwitcherNavigate.tsx"
|
|
289
|
+
import { useRouter } from "@tanstack/react-router";
|
|
290
|
+
import { Locales, getLocalizedUrl } from "intlayer";
|
|
291
|
+
import { useLocale } from "react-intlayer";
|
|
292
|
+
|
|
293
|
+
export function LocaleSwitcherNavigate() {
|
|
294
|
+
const router = useRouter();
|
|
295
|
+
const { locale, setLocale } = useLocale();
|
|
296
|
+
|
|
297
|
+
const change = async (next: Locales) => {
|
|
298
|
+
if (next === locale) return;
|
|
299
|
+
const nextPath = getLocalizedUrl(
|
|
300
|
+
window.location.pathname + window.location.search,
|
|
301
|
+
next
|
|
302
|
+
);
|
|
303
|
+
await router.navigate({ to: nextPath }); // сохраняет историю
|
|
304
|
+
setLocale(next);
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
return (
|
|
308
|
+
<div className="flex gap-2">
|
|
309
|
+
<button onClick={() => change(Locales.ENGLISH)}>English</button>
|
|
310
|
+
<button onClick={() => change(Locales.FRENCH)}>Français</button>
|
|
311
|
+
<button onClick={() => change(Locales.SPANISH)}>Español</button>
|
|
312
|
+
</div>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## (Необязательно) Шаг 9: `<html lang>` и `dir` (TanStack Start Document)
|
|
320
|
+
|
|
321
|
+
TanStack Start предоставляет **Document** (корневой HTML-шаблон), который вы можете настроить. Установите `lang` и `dir` для доступности и SEO:
|
|
322
|
+
|
|
323
|
+
```tsx fileName="src/routes/__root.tsx" {4,15}
|
|
324
|
+
import { Outlet, createRootRoute } from "@tanstack/react-router";
|
|
325
|
+
import { IntlayerProvider } from "react-intlayer";
|
|
326
|
+
import { getHTMLTextDir } from "intlayer";
|
|
327
|
+
|
|
328
|
+
function Document({
|
|
329
|
+
locale,
|
|
330
|
+
children,
|
|
331
|
+
}: {
|
|
332
|
+
locale: string;
|
|
333
|
+
children: React.ReactNode;
|
|
334
|
+
}) {
|
|
335
|
+
return (
|
|
336
|
+
<html lang={locale} dir={getHTMLTextDir(locale)}>
|
|
337
|
+
<head>
|
|
338
|
+
<meta charSet="utf-8" />
|
|
339
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
340
|
+
{/* ... */}
|
|
341
|
+
</head>
|
|
342
|
+
<body>{children}</body>
|
|
343
|
+
</html>
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export const Route = createRootRoute({
|
|
348
|
+
component: () => (
|
|
349
|
+
<IntlayerProvider>
|
|
350
|
+
{/* Если вы вычисляете локаль на сервере, передайте её в Document; иначе клиент исправит после гидратации */}
|
|
351
|
+
<Document locale={document?.documentElement?.lang || "en"}>
|
|
352
|
+
<Outlet />
|
|
353
|
+
</Document>
|
|
354
|
+
</IntlayerProvider>
|
|
355
|
+
),
|
|
356
|
+
});
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Для исправления на стороне клиента вы также можете использовать небольшой хук:
|
|
360
|
+
|
|
361
|
+
```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx"
|
|
362
|
+
import { useEffect } from "react";
|
|
363
|
+
import { useLocale } from "react-intlayer";
|
|
364
|
+
import { getHTMLTextDir } from "intlayer";
|
|
365
|
+
|
|
366
|
+
export const useI18nHTMLAttributes = () => {
|
|
367
|
+
const { locale } = useLocale();
|
|
368
|
+
useEffect(() => {
|
|
369
|
+
document.documentElement.lang = locale; // Устанавливаем атрибут lang для документа
|
|
370
|
+
document.documentElement.dir = getHTMLTextDir(locale); // Устанавливаем направление текста (ltr или rtl) в зависимости от локали
|
|
371
|
+
}, [locale]);
|
|
372
|
+
};
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## (Необязательно) Шаг 10: Локализованный компонент Link
|
|
378
|
+
|
|
379
|
+
TanStack Router предоставляет компонент `<Link/>`, но если вам когда-либо понадобится простой `<a>`, который автоматически добавляет префикс локали к внутренним URL:
|
|
380
|
+
|
|
381
|
+
```tsx fileName="src/components/Link.tsx"
|
|
382
|
+
import { getLocalizedUrl } from "intlayer";
|
|
383
|
+
import {
|
|
384
|
+
forwardRef,
|
|
385
|
+
type AnchorHTMLAttributes,
|
|
386
|
+
type DetailedHTMLProps,
|
|
387
|
+
} from "react";
|
|
388
|
+
import { useLocale } from "react-intlayer";
|
|
389
|
+
|
|
390
|
+
export interface LinkProps
|
|
391
|
+
extends DetailedHTMLProps<
|
|
392
|
+
AnchorHTMLAttributes<HTMLAnchorElement>,
|
|
393
|
+
HTMLAnchorElement
|
|
394
|
+
> {}
|
|
395
|
+
|
|
396
|
+
const isExternal = (href?: string) => /^https?:\/\//.test(href ?? "");
|
|
397
|
+
|
|
398
|
+
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
|
|
399
|
+
({ href, children, ...props }, ref) => {
|
|
400
|
+
const { locale } = useLocale();
|
|
401
|
+
const hrefI18n =
|
|
402
|
+
href && !isExternal(href) ? getLocalizedUrl(href, locale) : href;
|
|
403
|
+
return (
|
|
404
|
+
<a href={hrefI18n} ref={ref} {...props}>
|
|
405
|
+
{children}
|
|
406
|
+
</a>
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
);
|
|
410
|
+
Link.displayName = "Link";
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
> Если вы используете шаблон A (basepath), то `<Link to="/about" />` из TanStack уже преобразуется в `/fr/about` через `basepath`, поэтому кастомная ссылка является необязательной.
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## TypeScript
|
|
418
|
+
|
|
419
|
+
Включите сгенерированные Intlayer типы:
|
|
420
|
+
|
|
421
|
+
```json5 fileName="tsconfig.json"
|
|
422
|
+
{
|
|
423
|
+
"include": ["src", ".intlayer/**/*.ts"],
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## Git
|
|
430
|
+
|
|
431
|
+
Игнорируйте сгенерированные артефакты Intlayer:
|
|
432
|
+
|
|
433
|
+
```gitignore
|
|
434
|
+
.intlayer
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## Расширение VS Code
|
|
440
|
+
|
|
441
|
+
- **Расширение Intlayer для VS Code** → автодополнение, ошибки, встроенные превью, быстрые действия.
|
|
442
|
+
Marketplace: `intlayer.intlayer-vs-code-extension`
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## Дальнейшие шаги
|
|
447
|
+
|
|
448
|
+
- Визуальный редактор
|
|
449
|
+
- Режим CMS
|
|
450
|
+
- Определение локали на краю / адаптеры
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## История документации
|
|
455
|
+
|
|
456
|
+
| Версия | Дата | Изменения |
|
|
457
|
+
| ------ | ---------- | ---------------------------------- |
|
|
458
|
+
| 1.0.0 | 2025-08-11 | Добавлена адаптация TanStack Start |
|
|
@@ -279,7 +279,6 @@ Intlayer предоставляет множество функций, кото
|
|
|
279
279
|
- [`useIntlayer()`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/next-intlayer/useIntlayer.md)
|
|
280
280
|
- [`useDictionary()`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/next-intlayer/useDictionary.md)
|
|
281
281
|
- [`useLocale()`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/next-intlayer/useLocale.md)
|
|
282
|
-
- [`useIntlayerAsync()`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/next-intlayer/useIntlayerAsync.md)
|
|
283
282
|
|
|
284
283
|
## История документации
|
|
285
284
|
|
|
@@ -274,7 +274,6 @@ Intlayer предоставляет множество функций, кото
|
|
|
274
274
|
- [`useIntlayer()`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useIntlayer.md)
|
|
275
275
|
- [`useDictionary()`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useDictionary.md)
|
|
276
276
|
- [`useLocale()`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useLocale.md)
|
|
277
|
-
- [`useIntlayerAsync()`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useIntlayerAsync.md)
|
|
278
277
|
|
|
279
278
|
## История документации
|
|
280
279
|
|