@intlayer/docs 7.0.4-canary.0 → 7.0.5
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/blog/ar/intlayer_with_i18next.md +68 -106
- package/blog/ar/intlayer_with_next-i18next.md +84 -288
- package/blog/ar/intlayer_with_next-intl.md +58 -337
- package/blog/ar/intlayer_with_react-i18next.md +68 -290
- package/blog/ar/intlayer_with_react-intl.md +63 -266
- package/blog/de/intlayer_with_i18next.md +77 -97
- package/blog/de/intlayer_with_next-i18next.md +69 -296
- package/blog/de/intlayer_with_next-intl.md +59 -340
- package/blog/de/intlayer_with_react-i18next.md +68 -290
- package/blog/de/intlayer_with_react-intl.md +62 -264
- package/blog/en/intlayer_with_i18next.md +36 -1638
- package/blog/en/intlayer_with_next-i18next.md +22 -847
- package/blog/en/intlayer_with_next-intl.md +32 -1053
- package/blog/en/intlayer_with_react-i18next.md +38 -764
- package/blog/en/intlayer_with_react-intl.md +42 -1018
- package/blog/en-GB/intlayer_with_i18next.md +67 -103
- package/blog/en-GB/intlayer_with_next-i18next.md +71 -292
- package/blog/en-GB/intlayer_with_next-intl.md +58 -337
- package/blog/en-GB/intlayer_with_react-i18next.md +67 -289
- package/blog/en-GB/intlayer_with_react-intl.md +61 -264
- package/blog/es/intlayer_with_i18next.md +67 -103
- package/blog/es/intlayer_with_next-i18next.md +71 -296
- package/blog/es/intlayer_with_next-intl.md +57 -338
- package/blog/es/intlayer_with_react-i18next.md +68 -290
- package/blog/es/intlayer_with_react-intl.md +62 -265
- package/blog/fr/intlayer_with_i18next.md +66 -104
- package/blog/fr/intlayer_with_next-i18next.md +82 -285
- package/blog/fr/intlayer_with_next-intl.md +57 -338
- package/blog/fr/intlayer_with_react-i18next.md +67 -289
- package/blog/fr/intlayer_with_react-intl.md +61 -264
- package/blog/hi/intlayer_with_i18next.md +68 -104
- package/blog/hi/intlayer_with_next-i18next.md +74 -299
- package/blog/hi/intlayer_with_next-intl.md +57 -239
- package/blog/hi/intlayer_with_react-i18next.md +69 -291
- package/blog/hi/intlayer_with_react-intl.md +65 -268
- package/blog/id/intlayer_with_i18next.md +126 -0
- package/blog/id/intlayer_with_next-i18next.md +142 -0
- package/blog/id/intlayer_with_next-intl.md +113 -0
- package/blog/id/intlayer_with_react-i18next.md +124 -0
- package/blog/id/intlayer_with_react-intl.md +122 -0
- package/blog/it/intlayer_with_i18next.md +67 -103
- package/blog/it/intlayer_with_next-i18next.md +71 -296
- package/blog/it/intlayer_with_next-intl.md +57 -338
- package/blog/it/intlayer_with_react-i18next.md +68 -290
- package/blog/it/intlayer_with_react-intl.md +62 -265
- package/blog/ja/intlayer_with_i18next.md +68 -103
- package/blog/ja/intlayer_with_next-i18next.md +85 -283
- package/blog/ja/intlayer_with_next-intl.md +58 -336
- package/blog/ja/intlayer_with_react-i18next.md +68 -290
- package/blog/ja/intlayer_with_react-intl.md +62 -264
- package/blog/ko/intlayer_with_i18next.md +80 -96
- package/blog/ko/intlayer_with_next-i18next.md +85 -287
- package/blog/ko/intlayer_with_next-intl.md +68 -327
- package/blog/ko/intlayer_with_react-i18next.md +68 -290
- package/blog/ko/intlayer_with_react-intl.md +64 -266
- package/blog/pl/intlayer_with_i18next.md +126 -0
- package/blog/pl/intlayer_with_next-i18next.md +142 -0
- package/blog/pl/intlayer_with_next-intl.md +111 -0
- package/blog/pl/intlayer_with_react-i18next.md +124 -0
- package/blog/pl/intlayer_with_react-intl.md +122 -0
- package/blog/pt/intlayer_with_i18next.md +67 -103
- package/blog/pt/intlayer_with_next-i18next.md +72 -293
- package/blog/pt/intlayer_with_next-intl.md +57 -256
- package/blog/pt/intlayer_with_react-i18next.md +104 -78
- package/blog/pt/intlayer_with_react-intl.md +62 -266
- package/blog/ru/intlayer_with_i18next.md +66 -104
- package/blog/ru/intlayer_with_next-i18next.md +71 -296
- package/blog/ru/intlayer_with_next-intl.md +58 -337
- package/blog/ru/intlayer_with_react-i18next.md +68 -290
- package/blog/ru/intlayer_with_react-intl.md +62 -265
- package/blog/tr/intlayer_with_i18next.md +71 -107
- package/blog/tr/intlayer_with_next-i18next.md +72 -297
- package/blog/tr/intlayer_with_next-intl.md +58 -339
- package/blog/tr/intlayer_with_react-i18next.md +69 -291
- package/blog/tr/intlayer_with_react-intl.md +63 -285
- package/blog/vi/intlayer_with_i18next.md +126 -0
- package/blog/vi/intlayer_with_next-i18next.md +142 -0
- package/blog/vi/intlayer_with_next-intl.md +111 -0
- package/blog/vi/intlayer_with_react-i18next.md +124 -0
- package/blog/vi/intlayer_with_react-intl.md +122 -0
- package/blog/zh/intlayer_with_i18next.md +67 -102
- package/blog/zh/intlayer_with_next-i18next.md +72 -296
- package/blog/zh/intlayer_with_next-intl.md +58 -336
- package/blog/zh/intlayer_with_react-i18next.md +68 -290
- package/blog/zh/intlayer_with_react-intl.md +63 -106
- package/docs/ar/plugins/sync-json.md +244 -0
- package/docs/de/plugins/sync-json.md +244 -0
- package/docs/en/intlayer_cli.md +25 -0
- package/docs/en/intlayer_with_nextjs_14.md +2 -0
- package/docs/en/intlayer_with_nextjs_15.md +2 -0
- package/docs/en/intlayer_with_nextjs_16.md +2 -0
- package/docs/en/plugins/sync-json.md +1 -1
- package/docs/en-GB/plugins/sync-json.md +244 -0
- package/docs/es/plugins/sync-json.md +244 -0
- package/docs/fr/plugins/sync-json.md +244 -0
- package/docs/hi/plugins/sync-json.md +244 -0
- package/docs/id/plugins/sync-json.md +244 -0
- package/docs/it/plugins/sync-json.md +244 -0
- package/docs/ja/plugins/sync-json.md +244 -0
- package/docs/ko/plugins/sync-json.md +244 -0
- package/docs/pl/plugins/sync-json.md +244 -0
- package/docs/pt/plugins/sync-json.md +244 -0
- package/docs/ru/plugins/sync-json.md +244 -0
- package/docs/tr/plugins/sync-json.md +245 -0
- package/docs/vi/plugins/sync-json.md +244 -0
- package/docs/zh/plugins/sync-json.md +244 -0
- package/package.json +14 -14
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-01-02
|
|
3
3
|
updatedAt: 2025-10-29
|
|
4
|
-
title: How to
|
|
5
|
-
description:
|
|
4
|
+
title: How to automate your react-i18next JSON translations using Intlayer
|
|
5
|
+
description: Automate your JSON translations with Intlayer and react-i18next for enhanced internationalization in React applications.
|
|
6
6
|
keywords:
|
|
7
7
|
- react-i18next
|
|
8
8
|
- i18next
|
|
@@ -23,186 +23,71 @@ history:
|
|
|
23
23
|
changes: Change to syncJSON plugin
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
## Table of Contents
|
|
29
|
-
|
|
30
|
-
<TOC/>
|
|
26
|
+
# How to automate your react-i18next JSON translations using Intlayer
|
|
31
27
|
|
|
32
28
|
## What is Intlayer?
|
|
33
29
|
|
|
34
|
-
**Intlayer** is an innovative, open-source internationalization
|
|
35
|
-
|
|
36
|
-
With Intlayer, you can:
|
|
37
|
-
|
|
38
|
-
- **Easily manage translations** using declarative dictionaries at the component level.
|
|
39
|
-
- **Dynamically localize content** with a flexible architecture.
|
|
40
|
-
- **Access translations** with full TypeScript support and autogenerated types.
|
|
41
|
-
- **Benefit from advanced features**, like dynamic locale detection, switching, and content externalization.
|
|
42
|
-
- **Integrate with existing i18n solutions** like react-i18next, next-intl, and react-intl.
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## Why Use Intlayer with react-i18next?
|
|
47
|
-
|
|
48
|
-
**react-i18next** is one of the most popular React integrations for **i18next**, providing hooks like `useTranslation` to fetch localized strings in your components. While powerful, react-i18next traditionally relies on JSON files organized in a centralized structure, which can lead to maintenance challenges as your application grows.
|
|
49
|
-
|
|
50
|
-
**Intlayer** enhances this workflow by offering:
|
|
51
|
-
|
|
52
|
-
### 1. **Flexible Component-Level Content Declaration**
|
|
53
|
-
|
|
54
|
-
With Intlayer, you can place content declaration files right next to the components that need them. This co-location prevents orphaned translations when components are moved or deleted.
|
|
55
|
-
|
|
56
|
-
**Example Structure:**
|
|
57
|
-
|
|
58
|
-
```bash codeFormat="typescript"
|
|
59
|
-
.
|
|
60
|
-
└── src
|
|
61
|
-
└── components
|
|
62
|
-
└── MyComponent
|
|
63
|
-
├── index.content.ts # Content declaration file
|
|
64
|
-
└── index.tsx
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
```bash codeFormat="esm"
|
|
68
|
-
.
|
|
69
|
-
└── src
|
|
70
|
-
└── components
|
|
71
|
-
└── MyComponent
|
|
72
|
-
├── index.content.mjs # Content declaration file
|
|
73
|
-
└── index.mjx
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
```bash codeFormat="commonjs"
|
|
77
|
-
.
|
|
78
|
-
└── src
|
|
79
|
-
└── components
|
|
80
|
-
└── MyComponent
|
|
81
|
-
├── index.content.cjs # Content declaration file
|
|
82
|
-
└── index.cjx
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
```bash codeFormat="json"
|
|
86
|
-
.
|
|
87
|
-
└── src
|
|
88
|
-
└── components
|
|
89
|
-
└── MyComponent
|
|
90
|
-
├── index.content.json # Content declaration file
|
|
91
|
-
└── index.jsx
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### 2. **Centralized Translations per Component**
|
|
95
|
-
|
|
96
|
-
A single content declaration file collects all necessary translations for a component. This makes missing translations easier to catch, especially when combined with TypeScript, which provides compile-time validation.
|
|
97
|
-
|
|
98
|
-
### 3. **Automated Dictionary Building**
|
|
99
|
-
|
|
100
|
-
Intlayer automatically transpiles your content declarations into i18next-compatible JSON files, eliminating manual JSON management.
|
|
30
|
+
**Intlayer** is an innovative, open-source internationalization library designed to address the shortcomings of traditional i18n solutions. It offers a modern approach to content management in React applications.
|
|
101
31
|
|
|
102
|
-
|
|
32
|
+
See a concrete comparison with react-i18next in our [react-i18next vs. react-intl vs. Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/blog/en/react-i18next_vs_react-intl_vs_intlayer.md) blog post.
|
|
103
33
|
|
|
104
|
-
|
|
105
|
-
- **Better Organization**: Keep translations close to their usage, improving code readability and maintainability.
|
|
106
|
-
- **Scalability**: Easily scale your internationalization strategy as your application grows.
|
|
34
|
+
## Why Combine Intlayer with react-i18next?
|
|
107
35
|
|
|
108
|
-
|
|
36
|
+
While Intlayer provides an excellent standalone i18n solution (see our [React integration guide](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_with_vite+react.md)), you might want to combine it with react-i18next for several reasons:
|
|
109
37
|
|
|
110
|
-
|
|
38
|
+
1. **Existing codebase**: You have an established react-i18next implementation and want to gradually migrate to Intlayer's improved developer experience.
|
|
39
|
+
2. **Legacy requirements**: Your project requires compatibility with existing react-i18next plugins or workflows.
|
|
40
|
+
3. **Team familiarity**: Your team is comfortable with react-i18next but wants better content management.
|
|
111
41
|
|
|
112
|
-
For
|
|
42
|
+
**For that, Intlayer can be implemented as an adapter for react-i18next to help automating your JSON translations in CLI or CI/CD pipelines, testing your translations, and more.**
|
|
113
43
|
|
|
114
|
-
|
|
44
|
+
This guide shows you how to leverage Intlayer's superior content declaration system while maintaining compatibility with react-i18next.
|
|
115
45
|
|
|
116
|
-
|
|
117
|
-
- **Intlayer** offers built-in **TypeScript support** with autogenerated types, whereas react-i18next requires additional configuration for type safety.
|
|
118
|
-
- **Intlayer** can integrate with react-i18next to provide the best of both worlds: component-level content management with the robust runtime features of i18next.
|
|
46
|
+
## Table of Contents
|
|
119
47
|
|
|
120
|
-
|
|
48
|
+
<TOC/>
|
|
121
49
|
|
|
122
50
|
## Step-by-Step Guide to Set Up Intlayer with react-i18next
|
|
123
51
|
|
|
124
52
|
### Step 1: Install Dependencies
|
|
125
53
|
|
|
126
|
-
Install the necessary packages
|
|
54
|
+
Install the necessary packages:
|
|
127
55
|
|
|
128
56
|
```bash packageManager="npm"
|
|
129
|
-
npm install intlayer
|
|
57
|
+
npm install intlayer @intlayer/sync-json-plugin
|
|
130
58
|
```
|
|
131
59
|
|
|
132
60
|
```bash packageManager="pnpm"
|
|
133
|
-
pnpm add intlayer
|
|
61
|
+
pnpm add intlayer @intlayer/sync-json-plugin
|
|
134
62
|
```
|
|
135
63
|
|
|
136
64
|
```bash packageManager="yarn"
|
|
137
|
-
yarn add intlayer
|
|
65
|
+
yarn add intlayer @intlayer/sync-json-plugin
|
|
138
66
|
```
|
|
139
67
|
|
|
140
|
-
|
|
68
|
+
**Package descriptions:**
|
|
141
69
|
|
|
142
|
-
- **intlayer
|
|
143
|
-
|
|
70
|
+
- **intlayer**: Core library for internationalization management, content declaration, and building
|
|
71
|
+
- **@intlayer/sync-json-plugin**: Plugin to export Intlayer content declarations to react-i18next compatible JSON format
|
|
144
72
|
|
|
145
|
-
|
|
146
|
-
React-specific integration library for i18next, including the `useTranslation` hook and other React bindings.
|
|
73
|
+
### Step 2: Implement the Intlayer plugin to wrap the JSON
|
|
147
74
|
|
|
148
|
-
|
|
149
|
-
The underlying framework for translation handling. It provides the core internationalization functionality.
|
|
75
|
+
Create an Intlayer configuration file to define your supported locales:
|
|
150
76
|
|
|
151
|
-
|
|
152
|
-
An i18next backend that dynamically imports JSON resources, enabling efficient lazy-loading of translations.
|
|
153
|
-
|
|
154
|
-
- **@intlayer/sync-json-plugin**
|
|
155
|
-
A plugin for Intlayer that automatically exports your content declarations as i18next-compatible JSON files.
|
|
156
|
-
|
|
157
|
-
---
|
|
77
|
+
**If you want to also export JSON dictionaries for react-i18next**, add the `syncJSON` plugin:
|
|
158
78
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
Create a configuration file to define the languages and settings for your application:
|
|
162
|
-
|
|
163
|
-
```typescript fileName="intlayer.config.ts" codeFormat="typescript"
|
|
79
|
+
```typescript fileName="intlayer.config.ts"
|
|
164
80
|
import { Locales, type IntlayerConfig } from "intlayer";
|
|
165
81
|
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
166
82
|
|
|
167
83
|
const config: IntlayerConfig = {
|
|
168
84
|
internationalization: {
|
|
169
|
-
locales: [
|
|
170
|
-
Locales.ENGLISH,
|
|
171
|
-
Locales.FRENCH,
|
|
172
|
-
Locales.SPANISH,
|
|
173
|
-
// Add your other locales
|
|
174
|
-
],
|
|
175
|
-
defaultLocale: Locales.ENGLISH,
|
|
176
|
-
},
|
|
177
|
-
plugins: [
|
|
178
|
-
syncJSON({
|
|
179
|
-
// Adjust the source path to match your desired output structure
|
|
180
|
-
source: ({ key, locale }) => `./intl/messages/${locale}/${key}.json`,
|
|
181
|
-
}),
|
|
182
|
-
],
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
export default config;
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
```javascript fileName="intlayer.config.mjs" codeFormat="esm"
|
|
189
|
-
import { Locales } from "intlayer";
|
|
190
|
-
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
191
|
-
|
|
192
|
-
/** @type {import('intlayer').IntlayerConfig} */
|
|
193
|
-
const config = {
|
|
194
|
-
internationalization: {
|
|
195
|
-
locales: [
|
|
196
|
-
Locales.ENGLISH,
|
|
197
|
-
Locales.FRENCH,
|
|
198
|
-
Locales.SPANISH,
|
|
199
|
-
// Add your other locales
|
|
200
|
-
],
|
|
85
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
201
86
|
defaultLocale: Locales.ENGLISH,
|
|
202
87
|
},
|
|
203
88
|
plugins: [
|
|
204
89
|
syncJSON({
|
|
205
|
-
source: ({ key, locale }) => `./
|
|
90
|
+
source: ({ key, locale }) => `./messages/${locale}/${key}.json`,
|
|
206
91
|
}),
|
|
207
92
|
],
|
|
208
93
|
};
|
|
@@ -210,641 +95,30 @@ const config = {
|
|
|
210
95
|
export default config;
|
|
211
96
|
```
|
|
212
97
|
|
|
213
|
-
|
|
214
|
-
const { Locales } = require("intlayer");
|
|
215
|
-
const { syncJSON } = require("@intlayer/sync-json-plugin");
|
|
216
|
-
|
|
217
|
-
/** @type {import('intlayer').IntlayerConfig} */
|
|
218
|
-
const config = {
|
|
219
|
-
internationalization: {
|
|
220
|
-
locales: [
|
|
221
|
-
Locales.ENGLISH,
|
|
222
|
-
Locales.FRENCH,
|
|
223
|
-
Locales.SPANISH,
|
|
224
|
-
// Add your other locales
|
|
225
|
-
],
|
|
226
|
-
defaultLocale: Locales.ENGLISH,
|
|
227
|
-
},
|
|
228
|
-
plugins: [
|
|
229
|
-
syncJSON({
|
|
230
|
-
source: ({ key, locale }) => `./intl/messages/${locale}/${key}.json`,
|
|
231
|
-
}),
|
|
232
|
-
],
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
module.exports = config;
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
> **Note**: Through this configuration file, you can customize content directory location, file extensions, output paths, and more. For a complete list of available parameters, refer to the [Intlayer configuration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/configuration.md).
|
|
239
|
-
|
|
240
|
-
---
|
|
241
|
-
|
|
242
|
-
### Step 3: Build the i18next Resources
|
|
243
|
-
|
|
244
|
-
Once your content declarations are in place (covered in Step 5), run the **Intlayer build command** to generate i18next-compatible JSON files:
|
|
245
|
-
|
|
246
|
-
```bash packageManager="npm"
|
|
247
|
-
npx intlayer build
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
```bash packageManager="pnpm"
|
|
251
|
-
pnpm intlayer build
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
```bash packageManager="yarn"
|
|
255
|
-
yarn intlayer build
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
> This command will scan your project for `*.content.{ts,tsx,js,jsx,mjs,cjs,json}` files, compile them, and write the output to the directory specified in your `intlayer.config.*` (by default, `./intl/messages`).
|
|
259
|
-
|
|
260
|
-
**Expected Output:**
|
|
261
|
-
|
|
262
|
-
```bash
|
|
263
|
-
.
|
|
264
|
-
└── intl
|
|
265
|
-
└── messages
|
|
266
|
-
├── en
|
|
267
|
-
│ ├── my-component.json
|
|
268
|
-
│ └── another-component.json
|
|
269
|
-
├── fr
|
|
270
|
-
│ ├── my-component.json
|
|
271
|
-
│ └── another-component.json
|
|
272
|
-
└── es
|
|
273
|
-
├── my-component.json
|
|
274
|
-
└── another-component.json
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
Each file corresponds to an **i18next namespace**, derived from the `key` in your Intlayer content declarations.
|
|
278
|
-
|
|
279
|
-
---
|
|
280
|
-
|
|
281
|
-
### Step 4: Integrate i18next in Your React Application
|
|
282
|
-
|
|
283
|
-
Configure i18next to load the generated JSON resources dynamically. Use the [`i18next-resources-to-backend`](https://www.npmjs.com/package/i18next-resources-to-backend) package for this purpose.
|
|
284
|
-
|
|
285
|
-
Create an `i18n` initialization file (e.g., `src/i18n.ts` or `src/i18n.js`):
|
|
286
|
-
|
|
287
|
-
```typescript fileName="src/i18n.ts" codeFormat="typescript"
|
|
288
|
-
import i18next from "i18next";
|
|
289
|
-
import { initReactI18next } from "react-i18next";
|
|
290
|
-
import resourcesToBackend from "i18next-resources-to-backend";
|
|
291
|
-
|
|
292
|
-
i18next
|
|
293
|
-
// react-i18next plugin
|
|
294
|
-
.use(initReactI18next)
|
|
295
|
-
// Dynamically load resources
|
|
296
|
-
.use(
|
|
297
|
-
resourcesToBackend((language: string, namespace: string) => {
|
|
298
|
-
// Adjust the import path to match your output directory
|
|
299
|
-
return import(`../intl/messages/${language}/${namespace}.json`);
|
|
300
|
-
})
|
|
301
|
-
)
|
|
302
|
-
// Initialize i18next
|
|
303
|
-
.init({
|
|
304
|
-
// Fallback locale
|
|
305
|
-
fallbackLng: "en",
|
|
306
|
-
|
|
307
|
-
// Enable debug mode during development
|
|
308
|
-
debug: process.env.NODE_ENV === "development",
|
|
309
|
-
|
|
310
|
-
// Namespaces to load by default (optional)
|
|
311
|
-
// defaultNS: "common",
|
|
312
|
-
|
|
313
|
-
// Other i18next configuration options
|
|
314
|
-
// See: https://www.i18next.com/overview/configuration-options
|
|
315
|
-
interpolation: {
|
|
316
|
-
escapeValue: false, // React already escapes values
|
|
317
|
-
},
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
export default i18next;
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
```javascript fileName="src/i18n.js" codeFormat="esm"
|
|
324
|
-
import i18next from "i18next";
|
|
325
|
-
import { initReactI18next } from "react-i18next";
|
|
326
|
-
import resourcesToBackend from "i18next-resources-to-backend";
|
|
327
|
-
|
|
328
|
-
i18next
|
|
329
|
-
.use(initReactI18next)
|
|
330
|
-
.use(
|
|
331
|
-
resourcesToBackend(
|
|
332
|
-
(language, namespace) =>
|
|
333
|
-
import(`../intl/messages/${language}/${namespace}.json`)
|
|
334
|
-
)
|
|
335
|
-
)
|
|
336
|
-
.init({
|
|
337
|
-
fallbackLng: "en",
|
|
338
|
-
debug: process.env.NODE_ENV === "development",
|
|
339
|
-
interpolation: {
|
|
340
|
-
escapeValue: false,
|
|
341
|
-
},
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
export default i18next;
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
```javascript fileName="src/i18n.cjs" codeFormat="commonjs"
|
|
348
|
-
const i18next = require("i18next");
|
|
349
|
-
const { initReactI18next } = require("react-i18next");
|
|
350
|
-
const resourcesToBackend = require("i18next-resources-to-backend");
|
|
351
|
-
|
|
352
|
-
i18next
|
|
353
|
-
.use(initReactI18next)
|
|
354
|
-
.use(
|
|
355
|
-
resourcesToBackend(
|
|
356
|
-
(language, namespace) =>
|
|
357
|
-
import(`../intl/messages/${language}/${namespace}.json`)
|
|
358
|
-
)
|
|
359
|
-
)
|
|
360
|
-
.init({
|
|
361
|
-
fallbackLng: "en",
|
|
362
|
-
debug: process.env.NODE_ENV === "development",
|
|
363
|
-
interpolation: {
|
|
364
|
-
escapeValue: false,
|
|
365
|
-
},
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
module.exports = i18next;
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
Then, import this i18n setup **before** rendering your application. In your root/index file (e.g., `src/index.tsx`):
|
|
372
|
-
|
|
373
|
-
```typescript fileName="src/index.tsx" codeFormat="typescript"
|
|
374
|
-
import React from "react";
|
|
375
|
-
import ReactDOM from "react-dom/client";
|
|
376
|
-
// Initialize i18n before anything else
|
|
377
|
-
import "./i18n";
|
|
378
|
-
import App from "./App";
|
|
379
|
-
|
|
380
|
-
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
|
381
|
-
<React.StrictMode>
|
|
382
|
-
<App />
|
|
383
|
-
</React.StrictMode>
|
|
384
|
-
);
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
```javascript fileName="src/index.jsx" codeFormat="esm"
|
|
388
|
-
import React from "react";
|
|
389
|
-
import ReactDOM from "react-dom/client";
|
|
390
|
-
import "./i18n";
|
|
391
|
-
import App from "./App";
|
|
392
|
-
|
|
393
|
-
ReactDOM.createRoot(document.getElementById("root")).render(
|
|
394
|
-
<React.StrictMode>
|
|
395
|
-
<App />
|
|
396
|
-
</React.StrictMode>
|
|
397
|
-
);
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
```javascript fileName="src/index.cjs" codeFormat="commonjs"
|
|
401
|
-
const React = require("react");
|
|
402
|
-
const ReactDOM = require("react-dom/client");
|
|
403
|
-
require("./i18n");
|
|
404
|
-
const App = require("./App");
|
|
98
|
+
The `syncJSON` plugin will automatically wrap the JSON. It will read and write the JSON files without changing the content architecture.
|
|
405
99
|
|
|
406
|
-
|
|
407
|
-
React.createElement(React.StrictMode, null, React.createElement(App))
|
|
408
|
-
);
|
|
409
|
-
```
|
|
100
|
+
If you want to make coexist that JSON with intlayer content declaration files (`.content` files), Intlayer will proceed this way:
|
|
410
101
|
|
|
411
|
-
|
|
102
|
+
1. load both JSON and content declaration files and transform them into a intlayer dictionary.
|
|
103
|
+
2. if there is conflicts between the JSON and the content declaration files, Intlayer will process to the merge of that all dictionaries. Depending of the priority of the plugins, and the one of the content declaration file (all are configurable).
|
|
412
104
|
|
|
413
|
-
|
|
105
|
+
If changes are made using the CLI to translate the JSON, or using the CMS, Intlayer will update the JSON file with the new translations.
|
|
414
106
|
|
|
415
|
-
|
|
107
|
+
To see more details about the `syncJSON` plugin, please refer to the [syncJSON plugin documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/plugins/sync-json.md).
|
|
416
108
|
|
|
417
|
-
|
|
109
|
+
## Git Configuration
|
|
418
110
|
|
|
419
|
-
|
|
420
|
-
import { t, type Dictionary } from "intlayer";
|
|
421
|
-
|
|
422
|
-
const myComponentContent = {
|
|
423
|
-
// The "key" becomes the i18next namespace
|
|
424
|
-
key: "my-component",
|
|
425
|
-
content: {
|
|
426
|
-
// Each call to "t" defines a translation node
|
|
427
|
-
heading: t({
|
|
428
|
-
en: "Welcome to My Component",
|
|
429
|
-
fr: "Bienvenue dans mon composant",
|
|
430
|
-
es: "Bienvenido a mi componente",
|
|
431
|
-
}),
|
|
432
|
-
description: t({
|
|
433
|
-
en: "This is a description of my component.",
|
|
434
|
-
fr: "Ceci est une description de mon composant.",
|
|
435
|
-
es: "Esta es una descripción de mi componente.",
|
|
436
|
-
}),
|
|
437
|
-
buttonText: t({
|
|
438
|
-
en: "Click Me",
|
|
439
|
-
fr: "Cliquez-moi",
|
|
440
|
-
es: "Haz clic en mí",
|
|
441
|
-
}),
|
|
442
|
-
},
|
|
443
|
-
} satisfies Dictionary;
|
|
444
|
-
|
|
445
|
-
export default myComponentContent;
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
```javascript fileName="src/components/MyComponent/MyComponent.content.mjs" contentDeclarationFormat="esm"
|
|
449
|
-
import { t } from "intlayer";
|
|
450
|
-
|
|
451
|
-
/** @type {import('intlayer').Dictionary} */
|
|
452
|
-
const myComponentContent = {
|
|
453
|
-
key: "my-component",
|
|
454
|
-
content: {
|
|
455
|
-
heading: t({
|
|
456
|
-
en: "Welcome to My Component",
|
|
457
|
-
fr: "Bienvenue dans mon composant",
|
|
458
|
-
es: "Bienvenido a mi componente",
|
|
459
|
-
}),
|
|
460
|
-
description: t({
|
|
461
|
-
en: "This is a description of my component.",
|
|
462
|
-
fr: "Ceci est une description de mon composant.",
|
|
463
|
-
es: "Esta es una descripción de mi componente.",
|
|
464
|
-
}),
|
|
465
|
-
buttonText: t({
|
|
466
|
-
en: "Click Me",
|
|
467
|
-
fr: "Cliquez-moi",
|
|
468
|
-
es: "Haz clic en mí",
|
|
469
|
-
}),
|
|
470
|
-
},
|
|
471
|
-
};
|
|
472
|
-
|
|
473
|
-
export default myComponentContent;
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
```javascript fileName="src/components/MyComponent/MyComponent.content.cjs" contentDeclarationFormat="commonjs"
|
|
477
|
-
const { t } = require("intlayer");
|
|
478
|
-
|
|
479
|
-
/** @type {import('intlayer').Dictionary} */
|
|
480
|
-
const myComponentContent = {
|
|
481
|
-
key: "my-component",
|
|
482
|
-
content: {
|
|
483
|
-
heading: t({
|
|
484
|
-
en: "Welcome to My Component",
|
|
485
|
-
fr: "Bienvenue dans mon composant",
|
|
486
|
-
es: "Bienvenido a mi componente",
|
|
487
|
-
}),
|
|
488
|
-
description: t({
|
|
489
|
-
en: "This is a description of my component.",
|
|
490
|
-
fr: "Ceci est une description de mon composant.",
|
|
491
|
-
es: "Esta es una descripción de mi componente.",
|
|
492
|
-
}),
|
|
493
|
-
buttonText: t({
|
|
494
|
-
en: "Click Me",
|
|
495
|
-
fr: "Cliquez-moi",
|
|
496
|
-
es: "Haz clic en mí",
|
|
497
|
-
}),
|
|
498
|
-
},
|
|
499
|
-
};
|
|
500
|
-
|
|
501
|
-
module.exports = myComponentContent;
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
```json fileName="src/components/MyComponent/MyComponent.content.json" contentDeclarationFormat="json"
|
|
505
|
-
{
|
|
506
|
-
"$schema": "https://intlayer.org/schema.json",
|
|
507
|
-
"key": "my-component",
|
|
508
|
-
"content": {
|
|
509
|
-
"heading": {
|
|
510
|
-
"nodeType": "translation",
|
|
511
|
-
"translation": {
|
|
512
|
-
"en": "Welcome to My Component",
|
|
513
|
-
"fr": "Bienvenue dans mon composant",
|
|
514
|
-
"es": "Bienvenido a mi componente"
|
|
515
|
-
}
|
|
516
|
-
},
|
|
517
|
-
"description": {
|
|
518
|
-
"nodeType": "translation",
|
|
519
|
-
"translation": {
|
|
520
|
-
"en": "This is a description of my component.",
|
|
521
|
-
"fr": "Ceci est une description de mon composant.",
|
|
522
|
-
"es": "Esta es una descripción de mi componente."
|
|
523
|
-
}
|
|
524
|
-
},
|
|
525
|
-
"buttonText": {
|
|
526
|
-
"nodeType": "translation",
|
|
527
|
-
"translation": {
|
|
528
|
-
"en": "Click Me",
|
|
529
|
-
"fr": "Cliquez-moi",
|
|
530
|
-
"es": "Haz clic en mí"
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
> **Note**: Your content declarations can be defined anywhere in your application, as long as they are included in the `contentDir` directory (by default, `./src`) and match the content declaration file extension (by default, `.content.{ts,tsx,js,jsx,mjs,cjs,json}`).
|
|
538
|
-
|
|
539
|
-
> For more details, refer to the [content declaration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/dictionary/content_file.md).
|
|
540
|
-
|
|
541
|
-
---
|
|
542
|
-
|
|
543
|
-
### Step 6: Utilize Content in Your Code
|
|
544
|
-
|
|
545
|
-
Access your content dictionaries throughout your application using the `useTranslation` hook from react-i18next:
|
|
546
|
-
|
|
547
|
-
```tsx fileName="src/components/MyComponent/MyComponent.tsx" codeFormat="typescript"
|
|
548
|
-
import type { FC } from "react";
|
|
549
|
-
import { useTranslation } from "react-i18next";
|
|
550
|
-
|
|
551
|
-
/**
|
|
552
|
-
* The i18next "namespace" is the Intlayer `key` from "MyComponent.content.ts"
|
|
553
|
-
* so we'll pass "my-component" to useTranslation().
|
|
554
|
-
*/
|
|
555
|
-
const MyComponent: FC = () => {
|
|
556
|
-
const { t } = useTranslation("my-component");
|
|
557
|
-
|
|
558
|
-
return (
|
|
559
|
-
<div>
|
|
560
|
-
<h1>{t("heading")}</h1>
|
|
561
|
-
<p>{t("description")}</p>
|
|
562
|
-
<button>{t("buttonText")}</button>
|
|
563
|
-
</div>
|
|
564
|
-
);
|
|
565
|
-
};
|
|
566
|
-
|
|
567
|
-
export default MyComponent;
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
```jsx fileName="src/components/MyComponent/MyComponent.jsx" codeFormat="esm"
|
|
571
|
-
import { useTranslation } from "react-i18next";
|
|
572
|
-
|
|
573
|
-
const MyComponent = () => {
|
|
574
|
-
const { t } = useTranslation("my-component");
|
|
575
|
-
|
|
576
|
-
return (
|
|
577
|
-
<div>
|
|
578
|
-
<h1>{t("heading")}</h1>
|
|
579
|
-
<p>{t("description")}</p>
|
|
580
|
-
<button>{t("buttonText")}</button>
|
|
581
|
-
</div>
|
|
582
|
-
);
|
|
583
|
-
};
|
|
584
|
-
|
|
585
|
-
export default MyComponent;
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
```jsx fileName="src/components/MyComponent/MyComponent.csx" codeFormat="commonjs"
|
|
589
|
-
const { useTranslation } = require("react-i18next");
|
|
590
|
-
|
|
591
|
-
const MyComponent = () => {
|
|
592
|
-
const { t } = useTranslation("my-component");
|
|
593
|
-
|
|
594
|
-
return (
|
|
595
|
-
<div>
|
|
596
|
-
<h1>{t("heading")}</h1>
|
|
597
|
-
<p>{t("description")}</p>
|
|
598
|
-
<button>{t("buttonText")}</button>
|
|
599
|
-
</div>
|
|
600
|
-
);
|
|
601
|
-
};
|
|
602
|
-
|
|
603
|
-
module.exports = MyComponent;
|
|
604
|
-
```
|
|
605
|
-
|
|
606
|
-
> **Key Point**: The `t` function references keys inside your generated JSON. For an Intlayer content entry named `heading`, you'll use `t("heading")`.
|
|
607
|
-
|
|
608
|
-
---
|
|
609
|
-
|
|
610
|
-
### (Optional) Step 7: Change the Language of Your Content
|
|
611
|
-
|
|
612
|
-
To allow users to switch languages dynamically, use the `changeLanguage` function provided by i18next. Here's an example of a simple locale switcher:
|
|
613
|
-
|
|
614
|
-
```tsx fileName="src/components/LocaleSwitcher/LocaleSwitcher.tsx" codeFormat="typescript"
|
|
615
|
-
import type { FC } from "react";
|
|
616
|
-
import { useTranslation } from "react-i18next";
|
|
617
|
-
|
|
618
|
-
const LocaleSwitcher: FC = () => {
|
|
619
|
-
const { i18n } = useTranslation();
|
|
620
|
-
|
|
621
|
-
const changeLanguage = (locale: string) => {
|
|
622
|
-
i18n.changeLanguage(locale);
|
|
623
|
-
};
|
|
624
|
-
|
|
625
|
-
return (
|
|
626
|
-
<div>
|
|
627
|
-
<button
|
|
628
|
-
onClick={() => changeLanguage("en")}
|
|
629
|
-
disabled={i18n.language === "en"}
|
|
630
|
-
>
|
|
631
|
-
English
|
|
632
|
-
</button>
|
|
633
|
-
<button
|
|
634
|
-
onClick={() => changeLanguage("fr")}
|
|
635
|
-
disabled={i18n.language === "fr"}
|
|
636
|
-
>
|
|
637
|
-
Français
|
|
638
|
-
</button>
|
|
639
|
-
<button
|
|
640
|
-
onClick={() => changeLanguage("es")}
|
|
641
|
-
disabled={i18n.language === "es"}
|
|
642
|
-
>
|
|
643
|
-
Español
|
|
644
|
-
</button>
|
|
645
|
-
</div>
|
|
646
|
-
);
|
|
647
|
-
};
|
|
648
|
-
|
|
649
|
-
export default LocaleSwitcher;
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
```jsx fileName="src/components/LocaleSwitcher/LocaleSwitcher.jsx" codeFormat="esm"
|
|
653
|
-
import { useTranslation } from "react-i18next";
|
|
654
|
-
|
|
655
|
-
const LocaleSwitcher = () => {
|
|
656
|
-
const { i18n } = useTranslation();
|
|
657
|
-
|
|
658
|
-
const changeLanguage = (locale) => {
|
|
659
|
-
i18n.changeLanguage(locale);
|
|
660
|
-
};
|
|
661
|
-
|
|
662
|
-
return (
|
|
663
|
-
<div>
|
|
664
|
-
<button
|
|
665
|
-
onClick={() => changeLanguage("en")}
|
|
666
|
-
disabled={i18n.language === "en"}
|
|
667
|
-
>
|
|
668
|
-
English
|
|
669
|
-
</button>
|
|
670
|
-
<button
|
|
671
|
-
onClick={() => changeLanguage("fr")}
|
|
672
|
-
disabled={i18n.language === "fr"}
|
|
673
|
-
>
|
|
674
|
-
Français
|
|
675
|
-
</button>
|
|
676
|
-
<button
|
|
677
|
-
onClick={() => changeLanguage("es")}
|
|
678
|
-
disabled={i18n.language === "es"}
|
|
679
|
-
>
|
|
680
|
-
Español
|
|
681
|
-
</button>
|
|
682
|
-
</div>
|
|
683
|
-
);
|
|
684
|
-
};
|
|
685
|
-
|
|
686
|
-
export default LocaleSwitcher;
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
```jsx fileName="src/components/LocaleSwitcher/LocaleSwitcher.csx" codeFormat="commonjs"
|
|
690
|
-
const { useTranslation } = require("react-i18next");
|
|
691
|
-
|
|
692
|
-
const LocaleSwitcher = () => {
|
|
693
|
-
const { i18n } = useTranslation();
|
|
694
|
-
|
|
695
|
-
const changeLanguage = (locale) => {
|
|
696
|
-
i18n.changeLanguage(locale);
|
|
697
|
-
};
|
|
698
|
-
|
|
699
|
-
return (
|
|
700
|
-
<div>
|
|
701
|
-
<button
|
|
702
|
-
onClick={() => changeLanguage("en")}
|
|
703
|
-
disabled={i18n.language === "en"}
|
|
704
|
-
>
|
|
705
|
-
English
|
|
706
|
-
</button>
|
|
707
|
-
<button
|
|
708
|
-
onClick={() => changeLanguage("fr")}
|
|
709
|
-
disabled={i18n.language === "fr"}
|
|
710
|
-
>
|
|
711
|
-
Français
|
|
712
|
-
</button>
|
|
713
|
-
<button
|
|
714
|
-
onClick={() => changeLanguage("es")}
|
|
715
|
-
disabled={i18n.language === "es"}
|
|
716
|
-
>
|
|
717
|
-
Español
|
|
718
|
-
</button>
|
|
719
|
-
</div>
|
|
720
|
-
);
|
|
721
|
-
};
|
|
722
|
-
|
|
723
|
-
module.exports = LocaleSwitcher;
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
---
|
|
727
|
-
|
|
728
|
-
### (Optional) Step 8: Integrate with Create React App Scripts (CRACO)
|
|
729
|
-
|
|
730
|
-
**react-intlayer** provides a CRACO-based approach for custom builds and dev server configuration. If you want Intlayer's build step integrated seamlessly into your Create React App workflow, follow these steps:
|
|
731
|
-
|
|
732
|
-
1. **Install react-intlayer** (if you haven't):
|
|
733
|
-
|
|
734
|
-
```bash packageManager="npm"
|
|
735
|
-
npm install react-intlayer --save-dev
|
|
736
|
-
```
|
|
737
|
-
|
|
738
|
-
```bash packageManager="pnpm"
|
|
739
|
-
pnpm add react-intlayer --save-dev
|
|
740
|
-
```
|
|
741
|
-
|
|
742
|
-
```bash packageManager="yarn"
|
|
743
|
-
yarn add react-intlayer --save-dev
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
2. **Adjust your `package.json` scripts** to use `react-intlayer` scripts:
|
|
747
|
-
|
|
748
|
-
```json fileName="package.json"
|
|
749
|
-
{
|
|
750
|
-
"scripts": {
|
|
751
|
-
"start": "react-intlayer start",
|
|
752
|
-
"build": "react-intlayer build",
|
|
753
|
-
"transpile": "intlayer build"
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
```
|
|
757
|
-
|
|
758
|
-
> The `react-intlayer` scripts are based on [CRACO](https://craco.js.org/). You can also implement your own setup based on the intlayer craco plugin. [See example here](https://github.com/aymericzip/intlayer/blob/main/examples/react-app/craco.config.js).
|
|
759
|
-
|
|
760
|
-
Now, running `npm run build`, `yarn build`, or `pnpm build` triggers both Intlayer and CRA builds.
|
|
761
|
-
|
|
762
|
-
---
|
|
763
|
-
|
|
764
|
-
### (Optional) Step 9: Optimize Your Bundle Size
|
|
765
|
-
|
|
766
|
-
As your application scales, you may want to optimize the bundle size by ensuring only the required translations are loaded. While i18next with `i18next-resources-to-backend` already provides lazy-loading capabilities, you can further optimize by:
|
|
767
|
-
|
|
768
|
-
- **Code-Splitting**: Use dynamic imports to load components and their translations on demand.
|
|
769
|
-
- **Tree-Shaking**: Ensure your build tool (e.g., Webpack, Vite) is configured to remove unused code.
|
|
770
|
-
- **Namespace Splitting**: Split translations into multiple namespaces and load them as needed.
|
|
771
|
-
|
|
772
|
-
For more optimization techniques, refer to the [i18next documentation](https://www.i18next.com/principles/performance) and your build tool's documentation.
|
|
773
|
-
|
|
774
|
-
---
|
|
775
|
-
|
|
776
|
-
### Configure TypeScript
|
|
777
|
-
|
|
778
|
-
**Intlayer** provides **autogenerated type definitions** for your content, enabling TypeScript autocompletion and error detection.
|
|
779
|
-
|
|
780
|
-
To ensure TypeScript picks them up, add the autogenerated types directory to your `tsconfig.json` **include** array:
|
|
781
|
-
|
|
782
|
-
```json5 fileName="tsconfig.json"
|
|
783
|
-
{
|
|
784
|
-
"compilerOptions": {
|
|
785
|
-
// Your existing TypeScript configurations
|
|
786
|
-
},
|
|
787
|
-
"include": [
|
|
788
|
-
"src",
|
|
789
|
-
"types", // Include the auto-generated types
|
|
790
|
-
],
|
|
791
|
-
}
|
|
792
|
-
```
|
|
793
|
-
|
|
794
|
-
> This enables TypeScript to infer the shape of your translations, providing better autocompletion and compile-time error detection.
|
|
795
|
-
|
|
796
|
-
---
|
|
797
|
-
|
|
798
|
-
### Git Configuration
|
|
799
|
-
|
|
800
|
-
It is recommended to **ignore** auto-generated files and folders from Intlayer. This avoids committing them to your Git repository.
|
|
801
|
-
|
|
802
|
-
Add the following lines to your `.gitignore` file:
|
|
111
|
+
It's recommended to ignore auto-generated Intlayer files:
|
|
803
112
|
|
|
804
113
|
```plaintext fileName=".gitignore"
|
|
805
|
-
# Ignore
|
|
114
|
+
# Ignore files generated by Intlayer
|
|
806
115
|
.intlayer
|
|
807
|
-
intl
|
|
808
116
|
```
|
|
809
117
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
---
|
|
118
|
+
These files can be regenerated during your build process and don't need to be committed to version control.
|
|
813
119
|
|
|
814
120
|
### VS Code Extension
|
|
815
121
|
|
|
816
|
-
|
|
122
|
+
For improved developer experience, install the official **Intlayer VS Code Extension**:
|
|
817
123
|
|
|
818
124
|
[Install from the VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
|
|
819
|
-
|
|
820
|
-
This extension provides:
|
|
821
|
-
|
|
822
|
-
- **Autocompletion** for translation keys.
|
|
823
|
-
- **Real-time error detection** for missing translations.
|
|
824
|
-
- **Inline previews** of translated content.
|
|
825
|
-
- **Quick actions** to easily create and update translations.
|
|
826
|
-
|
|
827
|
-
For more details, refer to the [Intlayer VS Code Extension documentation](https://intlayer.org/doc/vs-code-extension).
|
|
828
|
-
|
|
829
|
-
---
|
|
830
|
-
|
|
831
|
-
### Go Further
|
|
832
|
-
|
|
833
|
-
To explore more advanced use cases and integrations:
|
|
834
|
-
|
|
835
|
-
- **[Intlayer Visual Editor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_visual_editor.md)**: Use the visual editor to manage translations directly from your application UI.
|
|
836
|
-
- **[Intlayer CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_CMS.md)**: Externalize your content management using the Intlayer CMS for seamless collaboration with non-technical team members.
|
|
837
|
-
- **[Intlayer with Next.js](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_with_nextjs_16.md)**: Learn how to integrate Intlayer with Next.js for server-side rendering and static site generation.
|
|
838
|
-
|
|
839
|
-
---
|
|
840
|
-
|
|
841
|
-
## Conclusion
|
|
842
|
-
|
|
843
|
-
By integrating **Intlayer** with **react-i18next**, you combine the best of both worlds:
|
|
844
|
-
|
|
845
|
-
- **Component-level content management** with Intlayer's flexible, developer-friendly approach.
|
|
846
|
-
- **Robust runtime translation** with the proven capabilities of react-i18next.
|
|
847
|
-
- **TypeScript support** for type-safe translations and autocompletion.
|
|
848
|
-
- **Scalable architecture** that grows with your application.
|
|
849
|
-
|
|
850
|
-
This integration streamlines your internationalization workflow, reduces maintenance overhead, and provides a superior developer experience. Start building your multilingual React application today with Intlayer and react-i18next!
|