@intlayer/docs 7.0.3 → 7.0.4-canary.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/blog/en/intlayer_with_i18next.md +1620 -54
- package/blog/en/intlayer_with_next-i18next.md +763 -163
- package/blog/en/intlayer_with_next-intl.md +986 -217
- package/blog/en/intlayer_with_react-i18next.md +645 -147
- package/blog/en/intlayer_with_react-intl.md +900 -147
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- package/dist/cjs/generated/blog.entry.cjs +13 -1
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +13 -1
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +13 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/generated/legal.entry.cjs +13 -1
- package/dist/cjs/generated/legal.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +13 -2
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +13 -2
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/generated/frequentQuestions.entry.mjs +13 -2
- package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
- package/dist/esm/generated/legal.entry.mjs +13 -2
- package/dist/esm/generated/legal.entry.mjs.map +1 -1
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/dist/types/generated/frequentQuestions.entry.d.ts.map +1 -1
- package/dist/types/generated/legal.entry.d.ts.map +1 -1
- package/docs/de/releases/v7.md +1 -18
- package/docs/en/CI_CD.md +1 -1
- package/docs/en/configuration.md +1 -1
- package/docs/en/formatters.md +1 -1
- package/docs/en/how_works_intlayer.md +1 -1
- package/docs/en/intlayer_CMS.md +1 -1
- package/docs/en/intlayer_cli.md +1 -1
- package/docs/en/intlayer_with_nextjs_14.md +1 -1
- package/docs/en/intlayer_with_nextjs_15.md +1 -1
- package/docs/en/intlayer_with_nextjs_16.md +1 -1
- package/docs/en/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/en/intlayer_with_nuxt.md +1 -1
- package/docs/en/intlayer_with_react_native+expo.md +1 -1
- package/docs/en/intlayer_with_react_router_v7.md +1 -1
- package/docs/en/intlayer_with_tanstack.md +1 -1
- package/docs/en/intlayer_with_vite+preact.md +1 -1
- package/docs/en/intlayer_with_vite+react.md +1 -1
- package/docs/en/intlayer_with_vite+solid.md +1 -1
- package/docs/en/intlayer_with_vite+svelte.md +1 -1
- package/docs/en/intlayer_with_vite+vue.md +1 -1
- package/docs/en/roadmap.md +1 -1
- package/docs/es/releases/v7.md +1 -18
- package/docs/fr/intlayer_with_nextjs_16.md +2 -51
- package/docs/fr/releases/v7.md +1 -18
- package/docs/hi/intlayer_with_nextjs_16.md +3 -2
- package/docs/id/releases/v7.md +1 -18
- package/docs/it/releases/v7.md +1 -18
- package/docs/ja/intlayer_with_nextjs_16.md +44 -205
- package/docs/ja/releases/v7.md +1 -18
- package/docs/ko/releases/v7.md +1 -18
- package/docs/pt/intlayer_with_nextjs_16.md +1 -52
- package/package.json +14 -14
- package/src/generated/blog.entry.ts +26 -3
- package/src/generated/docs.entry.ts +26 -3
- package/src/generated/frequentQuestions.entry.ts +26 -3
- package/src/generated/legal.entry.ts +26 -3
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-01-02
|
|
3
3
|
updatedAt: 2025-10-29
|
|
4
|
-
title: Intlayer
|
|
5
|
-
description:
|
|
4
|
+
title: How to use Intlayer with react-i18next – Complete i18n Guide 2025
|
|
5
|
+
description: Learn how to integrate Intlayer with react-i18next to build a fully internationalized React application. Comprehensive guide with step-by-step instructions, code examples, and best practices.
|
|
6
6
|
keywords:
|
|
7
7
|
- react-i18next
|
|
8
8
|
- i18next
|
|
9
9
|
- Intlayer
|
|
10
10
|
- Internationalization
|
|
11
|
+
- i18n
|
|
11
12
|
- Blog
|
|
12
|
-
- Next.js
|
|
13
|
-
- JavaScript
|
|
14
13
|
- React
|
|
14
|
+
- JavaScript
|
|
15
|
+
- TypeScript
|
|
16
|
+
- Content Management
|
|
15
17
|
slugs:
|
|
16
18
|
- blog
|
|
17
19
|
- intlayer-with-react-i18next
|
|
@@ -23,108 +25,159 @@ history:
|
|
|
23
25
|
|
|
24
26
|
# React Internationalization (i18n) with react-i18next and Intlayer
|
|
25
27
|
|
|
26
|
-
##
|
|
28
|
+
## Table of Contents
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
- **react-i18next** is a popular React integration for **i18next** that provides hooks like `useTranslation` to fetch localized strings in your components.
|
|
30
|
+
<TOC/>
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
## What is Intlayer?
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
**Intlayer** is an innovative, open-source internationalization (i18n) library designed to simplify multilingual support in modern web applications. Intlayer seamlessly integrates with popular frameworks like **React**, **Next.js**, **Vue**, and many others.
|
|
35
|
+
|
|
36
|
+
With Intlayer, you can:
|
|
34
37
|
|
|
35
|
-
|
|
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
|
+
---
|
|
36
45
|
|
|
37
46
|
## Why Use Intlayer with react-i18next?
|
|
38
47
|
|
|
39
|
-
**
|
|
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.
|
|
40
49
|
|
|
41
|
-
|
|
42
|
-
Put each content declaration file right next to the component that needs it. This structure allows you to keep translations co-located, preventing orphaned translations when components move or get deleted.
|
|
50
|
+
**Intlayer** enhances this workflow by offering:
|
|
43
51
|
|
|
44
|
-
|
|
45
|
-
.
|
|
46
|
-
└── src
|
|
47
|
-
└── components
|
|
48
|
-
└── MyComponent
|
|
49
|
-
├── index.content.ts # Content declaration file
|
|
50
|
-
└── index.tsx
|
|
51
|
-
```
|
|
52
|
+
### 1. **Flexible Component-Level Content Declaration**
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
.
|
|
55
|
-
└── src
|
|
56
|
-
└── components
|
|
57
|
-
└── MyComponent
|
|
58
|
-
├── index.content.mjs # Content declaration file
|
|
59
|
-
└── index.mjx
|
|
60
|
-
```
|
|
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.
|
|
61
55
|
|
|
62
|
-
|
|
63
|
-
.
|
|
64
|
-
└── src
|
|
65
|
-
└── components
|
|
66
|
-
└── MyComponent
|
|
67
|
-
├── index.content.cjs # Content declaration file
|
|
68
|
-
└── index.cjx
|
|
69
|
-
```
|
|
56
|
+
**Example Structure:**
|
|
70
57
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
58
|
+
```bash codeFormat="typescript"
|
|
59
|
+
.
|
|
60
|
+
└── src
|
|
61
|
+
└── components
|
|
62
|
+
└── MyComponent
|
|
63
|
+
├── index.content.ts # Content declaration file
|
|
64
|
+
└── index.tsx
|
|
65
|
+
```
|
|
79
66
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
67
|
+
```bash codeFormat="esm"
|
|
68
|
+
.
|
|
69
|
+
└── src
|
|
70
|
+
└── components
|
|
71
|
+
└── MyComponent
|
|
72
|
+
├── index.content.mjs # Content declaration file
|
|
73
|
+
└── index.mjx
|
|
74
|
+
```
|
|
83
75
|
|
|
84
|
-
|
|
76
|
+
```bash codeFormat="commonjs"
|
|
77
|
+
.
|
|
78
|
+
└── src
|
|
79
|
+
└── components
|
|
80
|
+
└── MyComponent
|
|
81
|
+
├── index.content.cjs # Content declaration file
|
|
82
|
+
└── index.cjx
|
|
83
|
+
```
|
|
85
84
|
|
|
86
|
-
|
|
85
|
+
```bash codeFormat="json"
|
|
86
|
+
.
|
|
87
|
+
└── src
|
|
88
|
+
└── components
|
|
89
|
+
└── MyComponent
|
|
90
|
+
├── index.content.json # Content declaration file
|
|
91
|
+
└── index.jsx
|
|
92
|
+
```
|
|
87
93
|
|
|
88
|
-
|
|
89
|
-
|
|
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.
|
|
101
|
+
|
|
102
|
+
### 4. **Enhanced Developer Experience**
|
|
103
|
+
|
|
104
|
+
- **Type Safety**: Autogenerated TypeScript types ensure autocompletion and error detection.
|
|
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.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Intlayer vs. react-i18next: Key Differences
|
|
111
|
+
|
|
112
|
+
For a comprehensive comparison of Intlayer with other i18n libraries for React (including react-i18next and react-intl), check out the [react-i18next vs. react-intl vs. Intlayer blog post](https://github.com/aymericzip/intlayer/blob/main/docs/blog/en/react-i18next_vs_react-intl_vs_intlayer.md).
|
|
113
|
+
|
|
114
|
+
**Key Takeaways:**
|
|
115
|
+
|
|
116
|
+
- **Intlayer** focuses on **component-level** content management, while react-i18next typically uses centralized JSON files.
|
|
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.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Step-by-Step Guide to Set Up Intlayer with react-i18next
|
|
123
|
+
|
|
124
|
+
### Step 1: Install Dependencies
|
|
125
|
+
|
|
126
|
+
Install the necessary packages using your preferred package manager:
|
|
127
|
+
|
|
128
|
+
```bash packageManager="npm"
|
|
90
129
|
npm install intlayer react-i18next i18next i18next-resources-to-backend @intlayer/sync-json-plugin
|
|
91
130
|
```
|
|
92
131
|
|
|
93
|
-
```bash
|
|
94
|
-
|
|
95
|
-
yarn add intlayer react-i18next i18next i18next-resources-to-backend @intlayer/sync-json-plugin
|
|
132
|
+
```bash packageManager="pnpm"
|
|
133
|
+
pnpm add intlayer react-i18next i18next i18next-resources-to-backend @intlayer/sync-json-plugin
|
|
96
134
|
```
|
|
97
135
|
|
|
98
|
-
```bash
|
|
99
|
-
|
|
100
|
-
pnpm add intlayer react-i18next i18next i18next-resources-to-backend @intlayer/sync-json-plugin
|
|
136
|
+
```bash packageManager="yarn"
|
|
137
|
+
yarn add intlayer react-i18next i18next i18next-resources-to-backend @intlayer/sync-json-plugin
|
|
101
138
|
```
|
|
102
139
|
|
|
103
|
-
|
|
140
|
+
#### What Are These Packages?
|
|
141
|
+
|
|
142
|
+
- **intlayer**
|
|
143
|
+
The core library that provides internationalization tools for configuration management, translation, content declaration, transpilation, and CLI commands.
|
|
144
|
+
|
|
145
|
+
- **react-i18next**
|
|
146
|
+
React-specific integration library for i18next, including the `useTranslation` hook and other React bindings.
|
|
104
147
|
|
|
105
|
-
- **
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
- **i18next**
|
|
109
|
-
|
|
110
|
-
|
|
148
|
+
- **i18next**
|
|
149
|
+
The underlying framework for translation handling. It provides the core internationalization functionality.
|
|
150
|
+
|
|
151
|
+
- **i18next-resources-to-backend**
|
|
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
|
+
---
|
|
111
158
|
|
|
112
|
-
|
|
159
|
+
### Step 2: Configure Your Project
|
|
113
160
|
|
|
114
|
-
Create
|
|
161
|
+
Create a configuration file to define the languages and settings for your application:
|
|
115
162
|
|
|
116
|
-
```typescript
|
|
163
|
+
```typescript fileName="intlayer.config.ts" codeFormat="typescript"
|
|
117
164
|
import { Locales, type IntlayerConfig } from "intlayer";
|
|
165
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
118
166
|
|
|
119
167
|
const config: IntlayerConfig = {
|
|
120
168
|
internationalization: {
|
|
121
|
-
|
|
122
|
-
|
|
169
|
+
locales: [
|
|
170
|
+
Locales.ENGLISH,
|
|
171
|
+
Locales.FRENCH,
|
|
172
|
+
Locales.SPANISH,
|
|
173
|
+
// Add your other locales
|
|
174
|
+
],
|
|
123
175
|
defaultLocale: Locales.ENGLISH,
|
|
124
176
|
},
|
|
125
177
|
plugins: [
|
|
126
178
|
syncJSON({
|
|
127
|
-
source
|
|
179
|
+
// Adjust the source path to match your desired output structure
|
|
180
|
+
source: ({ key, locale }) => `./intl/messages/${locale}/${key}.json`,
|
|
128
181
|
}),
|
|
129
182
|
],
|
|
130
183
|
};
|
|
@@ -132,50 +185,106 @@ const config: IntlayerConfig = {
|
|
|
132
185
|
export default config;
|
|
133
186
|
```
|
|
134
187
|
|
|
135
|
-
|
|
188
|
+
```javascript fileName="intlayer.config.mjs" codeFormat="esm"
|
|
189
|
+
import { Locales } from "intlayer";
|
|
190
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
136
191
|
|
|
137
|
-
|
|
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
|
+
],
|
|
201
|
+
defaultLocale: Locales.ENGLISH,
|
|
202
|
+
},
|
|
203
|
+
plugins: [
|
|
204
|
+
syncJSON({
|
|
205
|
+
source: ({ key, locale }) => `./intl/messages/${locale}/${key}.json`,
|
|
206
|
+
}),
|
|
207
|
+
],
|
|
208
|
+
};
|
|
138
209
|
|
|
139
|
-
|
|
210
|
+
export default config;
|
|
211
|
+
```
|
|
140
212
|
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
|
|
213
|
+
```javascript fileName="intlayer.config.cjs" codeFormat="commonjs"
|
|
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;
|
|
144
236
|
```
|
|
145
237
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
|
149
248
|
```
|
|
150
249
|
|
|
151
|
-
```bash
|
|
152
|
-
# With pnpm
|
|
250
|
+
```bash packageManager="pnpm"
|
|
153
251
|
pnpm intlayer build
|
|
154
252
|
```
|
|
155
253
|
|
|
156
|
-
|
|
254
|
+
```bash packageManager="yarn"
|
|
255
|
+
yarn intlayer build
|
|
256
|
+
```
|
|
157
257
|
|
|
158
|
-
|
|
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:**
|
|
159
261
|
|
|
160
262
|
```bash
|
|
161
263
|
.
|
|
162
|
-
└──
|
|
163
|
-
└──
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
|
170
275
|
```
|
|
171
276
|
|
|
172
|
-
|
|
277
|
+
Each file corresponds to an **i18next namespace**, derived from the `key` in your Intlayer content declarations.
|
|
173
278
|
|
|
174
|
-
|
|
279
|
+
---
|
|
175
280
|
|
|
176
|
-
|
|
281
|
+
### Step 4: Integrate i18next in Your React Application
|
|
177
282
|
|
|
178
|
-
|
|
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"
|
|
179
288
|
import i18next from "i18next";
|
|
180
289
|
import { initReactI18next } from "react-i18next";
|
|
181
290
|
import resourcesToBackend from "i18next-resources-to-backend";
|
|
@@ -183,11 +292,11 @@ import resourcesToBackend from "i18next-resources-to-backend";
|
|
|
183
292
|
i18next
|
|
184
293
|
// react-i18next plugin
|
|
185
294
|
.use(initReactI18next)
|
|
186
|
-
//
|
|
295
|
+
// Dynamically load resources
|
|
187
296
|
.use(
|
|
188
297
|
resourcesToBackend((language: string, namespace: string) => {
|
|
189
|
-
// Adjust the import path to your
|
|
190
|
-
return import(`../
|
|
298
|
+
// Adjust the import path to match your output directory
|
|
299
|
+
return import(`../intl/messages/${language}/${namespace}.json`);
|
|
191
300
|
})
|
|
192
301
|
)
|
|
193
302
|
// Initialize i18next
|
|
@@ -195,14 +304,23 @@ i18next
|
|
|
195
304
|
// Fallback locale
|
|
196
305
|
fallbackLng: "en",
|
|
197
306
|
|
|
198
|
-
//
|
|
199
|
-
|
|
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
|
+
},
|
|
200
318
|
});
|
|
201
319
|
|
|
202
320
|
export default i18next;
|
|
203
321
|
```
|
|
204
322
|
|
|
205
|
-
```javascript
|
|
323
|
+
```javascript fileName="src/i18n.js" codeFormat="esm"
|
|
206
324
|
import i18next from "i18next";
|
|
207
325
|
import { initReactI18next } from "react-i18next";
|
|
208
326
|
import resourcesToBackend from "i18next-resources-to-backend";
|
|
@@ -212,19 +330,47 @@ i18next
|
|
|
212
330
|
.use(
|
|
213
331
|
resourcesToBackend(
|
|
214
332
|
(language, namespace) =>
|
|
215
|
-
import(`../
|
|
333
|
+
import(`../intl/messages/${language}/${namespace}.json`)
|
|
216
334
|
)
|
|
217
335
|
)
|
|
218
336
|
.init({
|
|
219
337
|
fallbackLng: "en",
|
|
338
|
+
debug: process.env.NODE_ENV === "development",
|
|
339
|
+
interpolation: {
|
|
340
|
+
escapeValue: false,
|
|
341
|
+
},
|
|
220
342
|
});
|
|
221
343
|
|
|
222
344
|
export default i18next;
|
|
223
345
|
```
|
|
224
346
|
|
|
225
|
-
|
|
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
|
+
});
|
|
226
367
|
|
|
227
|
-
|
|
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"
|
|
228
374
|
import React from "react";
|
|
229
375
|
import ReactDOM from "react-dom/client";
|
|
230
376
|
// Initialize i18n before anything else
|
|
@@ -238,47 +384,167 @@ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
|
|
238
384
|
);
|
|
239
385
|
```
|
|
240
386
|
|
|
241
|
-
|
|
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");
|
|
405
|
+
|
|
406
|
+
ReactDOM.createRoot(document.getElementById("root")).render(
|
|
407
|
+
React.createElement(React.StrictMode, null, React.createElement(App))
|
|
408
|
+
);
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
### Step 5: Declare Your Content
|
|
414
|
+
|
|
415
|
+
Create and manage your content declarations to store translations. Intlayer content declaration files can be placed anywhere in your project, as long as they match the configured file pattern.
|
|
242
416
|
|
|
243
|
-
|
|
244
|
-
Here’s a minimal example in TypeScript:
|
|
417
|
+
**Example Content Declaration:**
|
|
245
418
|
|
|
246
|
-
```typescript
|
|
419
|
+
```typescript fileName="src/components/MyComponent/MyComponent.content.ts" contentDeclarationFormat="typescript"
|
|
247
420
|
import { t, type Dictionary } from "intlayer";
|
|
248
421
|
|
|
249
|
-
const
|
|
250
|
-
// The "key"
|
|
422
|
+
const myComponentContent = {
|
|
423
|
+
// The "key" becomes the i18next namespace
|
|
251
424
|
key: "my-component",
|
|
252
425
|
content: {
|
|
253
|
-
// Each "t"
|
|
426
|
+
// Each call to "t" defines a translation node
|
|
254
427
|
heading: t({
|
|
255
|
-
en: "
|
|
256
|
-
|
|
257
|
-
|
|
428
|
+
en: "Welcome to My Component",
|
|
429
|
+
fr: "Bienvenue dans mon composant",
|
|
430
|
+
es: "Bienvenido a mi componente",
|
|
258
431
|
}),
|
|
259
432
|
description: t({
|
|
260
|
-
en: "
|
|
261
|
-
fr: "
|
|
262
|
-
es: "
|
|
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í",
|
|
263
441
|
}),
|
|
264
442
|
},
|
|
265
443
|
} satisfies Dictionary;
|
|
266
444
|
|
|
267
|
-
export default
|
|
445
|
+
export default myComponentContent;
|
|
268
446
|
```
|
|
269
447
|
|
|
270
|
-
|
|
448
|
+
```javascript fileName="src/components/MyComponent/MyComponent.content.mjs" contentDeclarationFormat="esm"
|
|
449
|
+
import { t } from "intlayer";
|
|
271
450
|
|
|
272
|
-
|
|
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
|
+
};
|
|
273
472
|
|
|
274
|
-
|
|
473
|
+
export default myComponentContent;
|
|
474
|
+
```
|
|
275
475
|
|
|
276
|
-
|
|
476
|
+
```javascript fileName="src/components/MyComponent/MyComponent.content.cjs" contentDeclarationFormat="commonjs"
|
|
477
|
+
const { t } = require("intlayer");
|
|
277
478
|
|
|
278
|
-
|
|
279
|
-
|
|
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
|
+
};
|
|
280
500
|
|
|
281
|
-
|
|
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"
|
|
282
548
|
import type { FC } from "react";
|
|
283
549
|
import { useTranslation } from "react-i18next";
|
|
284
550
|
|
|
@@ -293,6 +559,7 @@ const MyComponent: FC = () => {
|
|
|
293
559
|
<div>
|
|
294
560
|
<h1>{t("heading")}</h1>
|
|
295
561
|
<p>{t("description")}</p>
|
|
562
|
+
<button>{t("buttonText")}</button>
|
|
296
563
|
</div>
|
|
297
564
|
);
|
|
298
565
|
};
|
|
@@ -300,53 +567,284 @@ const MyComponent: FC = () => {
|
|
|
300
567
|
export default MyComponent;
|
|
301
568
|
```
|
|
302
569
|
|
|
303
|
-
|
|
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
|
+
};
|
|
304
584
|
|
|
305
|
-
|
|
585
|
+
export default MyComponent;
|
|
586
|
+
```
|
|
306
587
|
|
|
307
|
-
|
|
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";
|
|
308
654
|
|
|
309
|
-
|
|
310
|
-
|
|
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"
|
|
311
735
|
npm install react-intlayer --save-dev
|
|
312
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
|
+
|
|
313
746
|
2. **Adjust your `package.json` scripts** to use `react-intlayer` scripts:
|
|
314
747
|
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
"
|
|
318
|
-
|
|
319
|
-
|
|
748
|
+
```json fileName="package.json"
|
|
749
|
+
{
|
|
750
|
+
"scripts": {
|
|
751
|
+
"start": "react-intlayer start",
|
|
752
|
+
"build": "react-intlayer build",
|
|
753
|
+
"transpile": "intlayer build"
|
|
754
|
+
}
|
|
320
755
|
}
|
|
321
756
|
```
|
|
322
757
|
|
|
323
|
-
> `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).
|
|
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).
|
|
324
759
|
|
|
325
760
|
Now, running `npm run build`, `yarn build`, or `pnpm build` triggers both Intlayer and CRA builds.
|
|
326
761
|
|
|
327
|
-
|
|
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.
|
|
328
779
|
|
|
329
|
-
|
|
780
|
+
To ensure TypeScript picks them up, add the autogenerated types directory to your `tsconfig.json` **include** array:
|
|
330
781
|
|
|
331
|
-
```json5
|
|
782
|
+
```json5 fileName="tsconfig.json"
|
|
332
783
|
{
|
|
333
784
|
"compilerOptions": {
|
|
334
|
-
//
|
|
785
|
+
// Your existing TypeScript configurations
|
|
335
786
|
},
|
|
336
|
-
"include": [
|
|
787
|
+
"include": [
|
|
788
|
+
"src",
|
|
789
|
+
"types", // Include the auto-generated types
|
|
790
|
+
],
|
|
337
791
|
}
|
|
338
792
|
```
|
|
339
793
|
|
|
340
|
-
> This
|
|
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
|
|
341
799
|
|
|
342
|
-
|
|
800
|
+
It is recommended to **ignore** auto-generated files and folders from Intlayer. This avoids committing them to your Git repository.
|
|
343
801
|
|
|
344
|
-
|
|
802
|
+
Add the following lines to your `.gitignore` file:
|
|
345
803
|
|
|
346
|
-
```plaintext
|
|
804
|
+
```plaintext fileName=".gitignore"
|
|
347
805
|
# Ignore the files generated by Intlayer
|
|
348
806
|
.intlayer
|
|
349
|
-
|
|
807
|
+
intl
|
|
350
808
|
```
|
|
351
809
|
|
|
352
810
|
You typically do **not** commit these resources or `.intlayer` internal build artifacts, as they can be regenerated on each build.
|
|
811
|
+
|
|
812
|
+
---
|
|
813
|
+
|
|
814
|
+
### VS Code Extension
|
|
815
|
+
|
|
816
|
+
To improve your development experience with Intlayer, consider installing the official **Intlayer VS Code Extension**.
|
|
817
|
+
|
|
818
|
+
[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!
|