intlayer 4.0.0 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +218 -157
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -17,25 +17,78 @@
|
|
|
17
17
|
</a>
|
|
18
18
|
</div>
|
|
19
19
|
|
|
20
|
-
#
|
|
20
|
+
# intlayer: Manage Multilingual Content Declaration (i18n)
|
|
21
21
|
|
|
22
|
-
**Intlayer** is
|
|
22
|
+
**Intlayer** is a suite of packages designed specifically for JavaScript developers. It is compatible with frameworks like React, Next.js, and Express.js.
|
|
23
|
+
|
|
24
|
+
**The `intlayer` package** allows you to declare your content anywhere in your code. It converts multilingual content declarations into structured dictionaries that integrate seamlessly into your application. With TypeScript, **Intlayer** enhances your development by providing stronger, more efficient tools.
|
|
25
|
+
|
|
26
|
+
## Why to integrate Intlayer?
|
|
27
|
+
|
|
28
|
+
- **JavaScript-Powered Content Management**: Harness the flexibility of JavaScript to define and manage your content efficiently.
|
|
29
|
+
- **Type-Safe Environment**: Leverage TypeScript to ensure all your content definitions are precise and error-free.
|
|
30
|
+
- **Integrated Content Files**: Keep your translations close to their respective components, enhancing maintainability and clarity.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
Install the necessary package using your preferred package manager:
|
|
35
|
+
|
|
36
|
+
```bash packageManager="npm"
|
|
37
|
+
npm install intlayer
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```bash packageManager="pnpm"
|
|
41
|
+
pnpm add intlayer
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```bash packageManager="yarn"
|
|
45
|
+
yarn add intlayer
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Configure Intlayer
|
|
49
|
+
|
|
50
|
+
Intlayer provides a configuration file to set up your project. Place this file in the root of your project.
|
|
51
|
+
|
|
52
|
+
```typescript fileName="intlayer.config.ts" codeFormat="typescript"
|
|
53
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
54
|
+
|
|
55
|
+
const config: IntlayerConfig = {
|
|
56
|
+
internationalization: {
|
|
57
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
58
|
+
defaultLocale: Locales.ENGLISH,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default config;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
> For a complete list of available parameters, refer to the [configuration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/en/configuration.md).
|
|
23
66
|
|
|
24
67
|
## Example of usage
|
|
25
68
|
|
|
26
|
-
|
|
69
|
+
With Intlayer, you can declare your content in a structured way anywhere in your codebase.
|
|
70
|
+
|
|
71
|
+
By default, Intlayer scans for files with the extension `.content.{ts,tsx,js,jsx,mjs,cjs}`.
|
|
72
|
+
|
|
73
|
+
> can modify the default extension by setting the `contentDir` property in the [configuration file](https://github.com/aymericzip/intlayer/blob/main/docs/en/configuration.md).
|
|
74
|
+
|
|
75
|
+
```bash codeFormat="typescript"
|
|
27
76
|
.
|
|
28
|
-
├──
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
77
|
+
├── intlayer.config.ts
|
|
78
|
+
└── src
|
|
79
|
+
├── ClientComponent
|
|
80
|
+
│ ├── index.content.ts
|
|
81
|
+
│ └── index.tsx
|
|
82
|
+
└── ServerComponent
|
|
83
|
+
├── index.content.ts
|
|
84
|
+
└── index.tsx
|
|
34
85
|
```
|
|
35
86
|
|
|
36
|
-
|
|
37
|
-
|
|
87
|
+
### Declare your content
|
|
88
|
+
|
|
89
|
+
Here’s an example of content declaration:
|
|
38
90
|
|
|
91
|
+
```tsx filePath="src/ClientComponent/index.content.ts" codeFormat="typescript"
|
|
39
92
|
import { type DeclarationContent, t } from "intlayer";
|
|
40
93
|
|
|
41
94
|
const clientComponentContent = {
|
|
@@ -46,195 +99,203 @@ const clientComponentContent = {
|
|
|
46
99
|
fr: "Bonjour le monde",
|
|
47
100
|
es: "Hola Mundo",
|
|
48
101
|
}),
|
|
102
|
+
numberOfCar: enu({
|
|
103
|
+
"<-1": "Less than minus one car",
|
|
104
|
+
"-1": "Minus one car",
|
|
105
|
+
"0": "No cars",
|
|
106
|
+
"1": "One car",
|
|
107
|
+
">5": "Some cars",
|
|
108
|
+
">19": "Many cars",
|
|
109
|
+
}),
|
|
49
110
|
},
|
|
50
111
|
} satisfies DeclarationContent;
|
|
51
112
|
|
|
52
113
|
export default clientComponentContent;
|
|
53
114
|
```
|
|
54
115
|
|
|
55
|
-
|
|
56
|
-
// ./ClientComponent/index.tsx
|
|
57
|
-
"use client";
|
|
116
|
+
### Build your dictionaries
|
|
58
117
|
|
|
59
|
-
|
|
118
|
+
You can build your dictionaries using the [intlayer-cli](https://github.com/aymericzip/intlayer/blob/main/packages/intlayer-cli/readme.md).
|
|
60
119
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return <span>{myTranslatedContent}</span>;
|
|
65
|
-
};
|
|
120
|
+
```bash packageManager="npm"
|
|
121
|
+
npx intlayer build
|
|
66
122
|
```
|
|
67
123
|
|
|
68
|
-
|
|
124
|
+
```bash packageManager="yarn"
|
|
125
|
+
yarn intlayer build
|
|
126
|
+
```
|
|
69
127
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
128
|
+
```bash packageManager="pnpm"
|
|
129
|
+
pnpm intlayer build
|
|
130
|
+
```
|
|
73
131
|
|
|
74
|
-
|
|
132
|
+
This command scans all `*.content.*` files, compiles them, and writes the results to the directory specified in your **`intlayer.config.ts`** (by default, `./.intlayer`).
|
|
75
133
|
|
|
76
|
-
|
|
134
|
+
A typical output might look like:
|
|
77
135
|
|
|
78
|
-
|
|
79
|
-
|
|
136
|
+
```bash
|
|
137
|
+
.
|
|
138
|
+
├── .intlayer
|
|
139
|
+
│ ├── dictionary # Contain the dictionary of your content
|
|
140
|
+
│ │ ├── client-component.json
|
|
141
|
+
│ │ └── server-component.json
|
|
142
|
+
│ ├── main # Contain the entry point of your dictionary to be used in your application
|
|
143
|
+
│ │ ├── dictionary.cjs
|
|
144
|
+
│ │ └── dictionary.mjs
|
|
145
|
+
│ └── types # Contain the auto-generated type definitions of your dictionary
|
|
146
|
+
│ ├── client-component.d.ts
|
|
147
|
+
│ └── server-component.d.ts
|
|
148
|
+
└── types
|
|
149
|
+
└── intlayer.d.ts # Contain the auto-generated type definitions of Intlayer
|
|
150
|
+
```
|
|
80
151
|
|
|
81
|
-
|
|
152
|
+
### Build i18next resources
|
|
82
153
|
|
|
83
|
-
|
|
154
|
+
Intlayer can be configured to build dictionaries for [i18next](https://www.i18next.com/). For that you need to add the following configuration to your `intlayer.config.ts` file:
|
|
84
155
|
|
|
85
|
-
|
|
156
|
+
```typescript fileName="intlayer.config.ts" codeFormat="typescript"
|
|
157
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
86
158
|
|
|
87
|
-
|
|
159
|
+
const config: IntlayerConfig = {
|
|
160
|
+
/* ... */
|
|
161
|
+
content: {
|
|
162
|
+
// Tells Intlayer to generate message files for i18next
|
|
163
|
+
dictionaryOutput: ["i18next"],
|
|
88
164
|
|
|
89
|
-
|
|
90
|
-
|
|
165
|
+
// The directory where Intlayer will write your message JSON files
|
|
166
|
+
i18nextResourcesDir: "./i18next/resources",
|
|
167
|
+
},
|
|
168
|
+
};
|
|
91
169
|
```
|
|
92
170
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
171
|
+
> For a complete list of available parameters, refer to the [configuration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/en/configuration.md).
|
|
172
|
+
|
|
173
|
+
Output:
|
|
96
174
|
|
|
97
175
|
```bash
|
|
98
|
-
|
|
176
|
+
.
|
|
177
|
+
└── i18next
|
|
178
|
+
└── resources
|
|
179
|
+
├── en
|
|
180
|
+
│ ├── client-component.json
|
|
181
|
+
│ └── server-component.json
|
|
182
|
+
├── es
|
|
183
|
+
│ ├── client-component.json
|
|
184
|
+
│ └── server-component.json
|
|
185
|
+
└── fr
|
|
186
|
+
├── client-component.json
|
|
187
|
+
└── server-component.json
|
|
99
188
|
```
|
|
100
189
|
|
|
101
|
-
|
|
190
|
+
For example, the **en/client-component.json** might look like:
|
|
191
|
+
|
|
192
|
+
```json filePath="intlayer/dictionary/en/client-component.json"
|
|
193
|
+
{
|
|
194
|
+
"myTranslatedContent": "Hello World",
|
|
195
|
+
"zero_numberOfCar": "No cars",
|
|
196
|
+
"one_numberOfCar": "One car",
|
|
197
|
+
"two_numberOfCar": "Two cars",
|
|
198
|
+
"other_numberOfCar": "Some cars"
|
|
199
|
+
}
|
|
200
|
+
```
|
|
102
201
|
|
|
103
|
-
|
|
202
|
+
### Build next-intl dictionaries
|
|
104
203
|
|
|
105
|
-
|
|
204
|
+
Intlayer can be configured to build dictionaries for [i18next](https://www.i18next.com/) or [next-intl](https://github.com/formatjs/react-intl/tree/main/packages/next-intl). For that you need to add the following configuration to your `intlayer.config.ts` file:
|
|
106
205
|
|
|
107
|
-
```typescript
|
|
108
|
-
|
|
109
|
-
import { t, enu, type DeclarationContent } from "intlayer";
|
|
206
|
+
```typescript fileName="intlayer.config.ts" codeFormat="typescript"
|
|
207
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
110
208
|
|
|
111
|
-
const
|
|
112
|
-
|
|
209
|
+
const config: IntlayerConfig = {
|
|
210
|
+
/* ... */
|
|
113
211
|
content: {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
en: "Get started by editing",
|
|
117
|
-
fr: "Commencez par éditer",
|
|
118
|
-
es: "Comience por editar",
|
|
119
|
-
}),
|
|
120
|
-
pageLink: "src/app/page.tsx",
|
|
121
|
-
},
|
|
122
|
-
nestedContent: {
|
|
123
|
-
id: "enumeration",
|
|
124
|
-
numberOfCar: enu({
|
|
125
|
-
"<-1": "Less than minus one car",
|
|
126
|
-
"-1": "Minus one car",
|
|
127
|
-
"0": "No cars",
|
|
128
|
-
"1": "One car",
|
|
129
|
-
">5": "Some cars",
|
|
130
|
-
">19": "Many cars",
|
|
131
|
-
}),
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
} satisfies DeclarationContent;
|
|
212
|
+
// Tells Intlayer to generate message files for i18next
|
|
213
|
+
dictionaryOutput: ["next-intl"],
|
|
135
214
|
|
|
136
|
-
//
|
|
137
|
-
|
|
215
|
+
// The directory where Intlayer will write your message JSON files
|
|
216
|
+
nextIntlMessagesDir: "./i18next/messages",
|
|
217
|
+
},
|
|
218
|
+
};
|
|
138
219
|
```
|
|
139
220
|
|
|
140
|
-
|
|
221
|
+
> For a complete list of available parameters, refer to the [configuration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/en/configuration.md).
|
|
141
222
|
|
|
142
|
-
|
|
143
|
-
// src/app/[locale]/page.content.mjs
|
|
223
|
+
Output:
|
|
144
224
|
|
|
145
|
-
|
|
225
|
+
```bash
|
|
226
|
+
.
|
|
227
|
+
└── intl
|
|
228
|
+
└── messages
|
|
229
|
+
├── en
|
|
230
|
+
│ ├── client-component.json
|
|
231
|
+
│ └── server-component.json
|
|
232
|
+
├── es
|
|
233
|
+
│ ├── client-component.json
|
|
234
|
+
│ └── server-component.json
|
|
235
|
+
└── fr
|
|
236
|
+
├── client-component.json
|
|
237
|
+
└── server-component.json
|
|
238
|
+
```
|
|
146
239
|
|
|
147
|
-
|
|
148
|
-
const pageContent = {
|
|
149
|
-
"key": "page",
|
|
150
|
-
getStarted: {
|
|
151
|
-
main: t({
|
|
152
|
-
en: "Get started by editing",
|
|
153
|
-
fr: "Commencez par éditer",
|
|
154
|
-
es: "Comience por editar",
|
|
155
|
-
}),
|
|
156
|
-
pageLink: "src/app/page.tsx",
|
|
157
|
-
},
|
|
158
|
-
nestedContent: {
|
|
159
|
-
id: "enumeration",
|
|
160
|
-
numberOfCar: enu({
|
|
161
|
-
"<-1": "Less than minus one car",
|
|
162
|
-
"-1": "Minus one car",
|
|
163
|
-
0: "No cars",
|
|
164
|
-
1: "One car",
|
|
165
|
-
">5": "Some cars",
|
|
166
|
-
">19": "Many cars",
|
|
167
|
-
}),
|
|
168
|
-
},
|
|
169
|
-
};
|
|
240
|
+
For example, the **en/client-component.json** might look like:
|
|
170
241
|
|
|
171
|
-
|
|
172
|
-
|
|
242
|
+
```json filePath="intlayer/dictionary/en/client-component.json"
|
|
243
|
+
{
|
|
244
|
+
"myTranslatedContent": "Hello World",
|
|
245
|
+
"zero_numberOfCar": "No cars",
|
|
246
|
+
"one_numberOfCar": "One car",
|
|
247
|
+
"two_numberOfCar": "Two cars",
|
|
248
|
+
"other_numberOfCar": "Some cars"
|
|
249
|
+
}
|
|
173
250
|
```
|
|
174
251
|
|
|
175
|
-
|
|
252
|
+
## CLI tools
|
|
176
253
|
|
|
177
|
-
|
|
178
|
-
// src/app/[locale]/page.content.cjs
|
|
254
|
+
Intlayer provides a CLI tool to:
|
|
179
255
|
|
|
180
|
-
|
|
256
|
+
- audit your content declarations and complete missing translations
|
|
257
|
+
- build dictionaries from your content declarations
|
|
258
|
+
- push and pull distant dictionaries from your CMS to your locale project
|
|
181
259
|
|
|
182
|
-
|
|
183
|
-
const pageContent = {
|
|
184
|
-
"key": "page",
|
|
185
|
-
getStarted: {
|
|
186
|
-
main: t({
|
|
187
|
-
en: "Get started by editing",
|
|
188
|
-
fr: "Commencez par éditer",
|
|
189
|
-
es: "Comience por editar",
|
|
190
|
-
}),
|
|
191
|
-
pageLink: "src/app/page.tsx",
|
|
192
|
-
},
|
|
193
|
-
nestedContent: {
|
|
194
|
-
id: "enumeration",
|
|
195
|
-
numberOfCar: enu({
|
|
196
|
-
"<-1": "Less than minus one car",
|
|
197
|
-
"-1": "Minus one car",
|
|
198
|
-
0: "No cars",
|
|
199
|
-
1: "One car",
|
|
200
|
-
">5": "Some cars",
|
|
201
|
-
">19": "Many cars",
|
|
202
|
-
}),
|
|
203
|
-
},
|
|
204
|
-
};
|
|
260
|
+
Consult [intlayer-cli](https://github.com/aymericzip/intlayer/blob/main/docs/en/intlayer_cli.md) for more information.
|
|
205
261
|
|
|
206
|
-
|
|
207
|
-
module.exports = pageContent;
|
|
208
|
-
```
|
|
262
|
+
## Use Intlayer into your application
|
|
209
263
|
|
|
210
|
-
|
|
264
|
+
One your content declared, you can consume your Intlayer dictionaries in your application.
|
|
211
265
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
266
|
+
Intlayer is available as a package for your application.
|
|
267
|
+
|
|
268
|
+
### React Application
|
|
269
|
+
|
|
270
|
+
To use Intlayer in your React application, you can use [react-intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/react-intlayer/index.md).
|
|
271
|
+
|
|
272
|
+
### Next.js Application
|
|
273
|
+
|
|
274
|
+
To use Intlayer in your Next.js application, you can use [next-intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/next-intlayer/index.md).
|
|
275
|
+
|
|
276
|
+
### Express Application
|
|
277
|
+
|
|
278
|
+
To use Intlayer in your Express application, you can use [express-intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/express-intlayer/index.md).
|
|
279
|
+
|
|
280
|
+
## Functions provided by `intlayer` package
|
|
281
|
+
|
|
282
|
+
The `intlayer` package also provides some functions to help you to internationalize your application.
|
|
283
|
+
|
|
284
|
+
- [`getConfiguration()`](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/intlayer/getConfiguration.md)
|
|
285
|
+
- [`getTranslationContent()`](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/intlayer/getTranslationContent.md)
|
|
286
|
+
- [`getEnumerationContent()`](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/intlayer/getEnumerationContent.md)
|
|
287
|
+
- [`getLocaleName()`](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/intlayer/getLocaleName.md)
|
|
288
|
+
- [`getLocaleLang()`](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/intlayer/getLocaleLang.md)
|
|
289
|
+
- [`getHTMLTextDir()`](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/intlayer/getHTMLTextDir.md)
|
|
290
|
+
- [`getPathWithoutLocale()`](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/intlayer/getPathWithoutLocale.md)
|
|
291
|
+
- [`getMultilingualUrls()`](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/intlayer/getMultilingualUrls.md)
|
|
292
|
+
- [`getLocalizedUrl()`](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/intlayer/getLocalizedUrl.md)
|
|
293
|
+
- [`getPathWithoutLocale()`](https://github.com/aymericzip/intlayer/blob/main/docs/en/packages/intlayer/getPathWithoutLocale.md)
|
|
294
|
+
|
|
295
|
+
## Read about Intlayer
|
|
296
|
+
|
|
297
|
+
- [Intlayer Website](https://intlayer.org)
|
|
298
|
+
- [Intlayer Documentation](https://intlayer.org/docs)
|
|
299
|
+
- [Intlayer GitHub](https://github.com/aymericzip/intlayer)
|
|
239
300
|
|
|
240
|
-
|
|
301
|
+
- [Ask your questions to our smart documentation](https://intlayer.org/docs/chat)
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "intlayer",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.3",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "Manage internationalization in a simple way, through TypeScript, declaration file, declare your multilingual every where in your code.",
|
|
5
|
+
"description": "Manage internationalization i18n in a simple way, through TypeScript, declaration file, declare your multilingual content every where in your code.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"intlayer",
|
|
8
8
|
"application",
|
|
@@ -58,9 +58,9 @@
|
|
|
58
58
|
"./package.json"
|
|
59
59
|
],
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@intlayer/cli": "4.0.
|
|
62
|
-
"@intlayer/
|
|
63
|
-
"@intlayer/
|
|
61
|
+
"@intlayer/cli": "4.0.3",
|
|
62
|
+
"@intlayer/core": "^4.0.3",
|
|
63
|
+
"@intlayer/config": "4.0.3"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@changesets/changelog-github": "0.5.0",
|
|
@@ -75,14 +75,14 @@
|
|
|
75
75
|
"tsup": "^8.3.5",
|
|
76
76
|
"typescript": "^5.7.3",
|
|
77
77
|
"@utils/ts-config": "1.0.4",
|
|
78
|
-
"@utils/ts-config-types": "1.0.4",
|
|
79
78
|
"@utils/tsup-config": "1.0.4",
|
|
79
|
+
"@utils/ts-config-types": "1.0.4",
|
|
80
80
|
"@utils/eslint-config": "1.0.4"
|
|
81
81
|
},
|
|
82
82
|
"peerDependencies": {
|
|
83
|
-
"@intlayer/
|
|
84
|
-
"@intlayer/
|
|
85
|
-
"@intlayer/core": "^4.0.
|
|
83
|
+
"@intlayer/config": "4.0.3",
|
|
84
|
+
"@intlayer/cli": "4.0.3",
|
|
85
|
+
"@intlayer/core": "^4.0.3"
|
|
86
86
|
},
|
|
87
87
|
"engines": {
|
|
88
88
|
"node": ">=14.18"
|