@intlayer/docs 8.9.4-canary.0 → 8.9.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/dist/cjs/generated/docs.entry.cjs +20 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +20 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/benchmark/index.md +0 -3
- package/docs/ar/benchmark/nextjs.md +15 -6
- package/docs/ar/benchmark/solid.md +155 -0
- package/docs/ar/benchmark/svelte.md +148 -0
- package/docs/ar/benchmark/tanstack.md +12 -3
- package/docs/ar/benchmark/vue.md +160 -0
- package/docs/ar/configuration.md +16 -12
- package/docs/ar/dictionary/content_file.md +51 -1
- package/docs/ar/mcp_server.md +30 -17
- package/docs/ar/plugins/sync-po.md +333 -0
- package/docs/bn/configuration.md +16 -12
- package/docs/cs/configuration.md +16 -12
- package/docs/de/benchmark/index.md +0 -3
- package/docs/de/benchmark/nextjs.md +15 -6
- package/docs/de/benchmark/solid.md +155 -0
- package/docs/de/benchmark/svelte.md +148 -0
- package/docs/de/benchmark/tanstack.md +12 -3
- package/docs/de/benchmark/vue.md +160 -0
- package/docs/de/configuration.md +16 -12
- package/docs/de/dictionary/content_file.md +52 -2
- package/docs/de/mcp_server.md +29 -16
- package/docs/de/plugins/sync-po.md +332 -0
- package/docs/en/benchmark/nextjs.md +11 -2
- package/docs/en/benchmark/solid.md +22 -4
- package/docs/en/benchmark/svelte.md +17 -5
- package/docs/en/benchmark/tanstack.md +18 -3
- package/docs/en/benchmark/vue.md +17 -11
- package/docs/en/configuration.md +16 -13
- package/docs/en/dictionary/content_file.md +51 -1
- package/docs/en/mcp_server.md +31 -18
- package/docs/en/plugins/sync-po.md +333 -0
- package/docs/en-GB/benchmark/index.md +0 -3
- package/docs/en-GB/benchmark/nextjs.md +15 -6
- package/docs/en-GB/benchmark/solid.md +155 -0
- package/docs/en-GB/benchmark/svelte.md +148 -0
- package/docs/en-GB/benchmark/tanstack.md +12 -3
- package/docs/en-GB/benchmark/vue.md +160 -0
- package/docs/en-GB/configuration.md +15 -11
- package/docs/en-GB/dictionary/content_file.md +51 -1
- package/docs/en-GB/mcp_server.md +31 -18
- package/docs/en-GB/plugins/sync-po.md +333 -0
- package/docs/es/benchmark/index.md +0 -3
- package/docs/es/benchmark/nextjs.md +15 -6
- package/docs/es/benchmark/solid.md +155 -0
- package/docs/es/benchmark/svelte.md +148 -0
- package/docs/es/benchmark/tanstack.md +12 -3
- package/docs/es/benchmark/vue.md +160 -0
- package/docs/es/configuration.md +16 -12
- package/docs/es/dictionary/content_file.md +51 -1
- package/docs/es/mcp_server.md +30 -17
- package/docs/es/plugins/sync-po.md +333 -0
- package/docs/fr/benchmark/index.md +0 -3
- package/docs/fr/benchmark/nextjs.md +15 -6
- package/docs/fr/benchmark/solid.md +155 -0
- package/docs/fr/benchmark/svelte.md +148 -0
- package/docs/fr/benchmark/tanstack.md +12 -3
- package/docs/fr/benchmark/vue.md +160 -0
- package/docs/fr/configuration.md +16 -12
- package/docs/fr/dictionary/content_file.md +51 -1
- package/docs/fr/mcp_server.md +30 -17
- package/docs/fr/plugins/sync-po.md +333 -0
- package/docs/hi/benchmark/nextjs.md +15 -6
- package/docs/hi/benchmark/solid.md +155 -0
- package/docs/hi/benchmark/svelte.md +148 -0
- package/docs/hi/benchmark/tanstack.md +12 -3
- package/docs/hi/benchmark/vue.md +160 -0
- package/docs/hi/configuration.md +16 -12
- package/docs/hi/dictionary/content_file.md +51 -1
- package/docs/hi/mcp_server.md +31 -18
- package/docs/hi/plugins/sync-po.md +333 -0
- package/docs/id/benchmark/index.md +0 -3
- package/docs/id/benchmark/nextjs.md +15 -6
- package/docs/id/benchmark/solid.md +155 -0
- package/docs/id/benchmark/svelte.md +148 -0
- package/docs/id/benchmark/tanstack.md +12 -3
- package/docs/id/benchmark/vue.md +160 -0
- package/docs/id/configuration.md +16 -12
- package/docs/id/dictionary/content_file.md +51 -1
- package/docs/id/mcp_server.md +30 -17
- package/docs/id/plugins/sync-po.md +333 -0
- package/docs/it/benchmark/index.md +1 -4
- package/docs/it/benchmark/nextjs.md +15 -6
- package/docs/it/benchmark/solid.md +155 -0
- package/docs/it/benchmark/svelte.md +148 -0
- package/docs/it/benchmark/tanstack.md +12 -3
- package/docs/it/benchmark/vue.md +160 -0
- package/docs/it/configuration.md +16 -12
- package/docs/it/dictionary/content_file.md +51 -1
- package/docs/it/mcp_server.md +30 -17
- package/docs/it/plugins/sync-po.md +333 -0
- package/docs/ja/benchmark/index.md +5 -5
- package/docs/ja/benchmark/nextjs.md +15 -6
- package/docs/ja/benchmark/solid.md +155 -0
- package/docs/ja/benchmark/svelte.md +148 -0
- package/docs/ja/benchmark/tanstack.md +12 -3
- package/docs/ja/benchmark/vue.md +160 -0
- package/docs/ja/configuration.md +16 -12
- package/docs/ja/dictionary/content_file.md +50 -2
- package/docs/ja/intlayer_with_nextjs_no_locale_path.md +4 -3
- package/docs/ja/mcp_server.md +29 -16
- package/docs/ja/plugins/sync-po.md +333 -0
- package/docs/ko/benchmark/nextjs.md +15 -6
- package/docs/ko/benchmark/solid.md +155 -0
- package/docs/ko/benchmark/svelte.md +148 -0
- package/docs/ko/benchmark/tanstack.md +12 -3
- package/docs/ko/benchmark/vue.md +160 -0
- package/docs/ko/configuration.md +16 -12
- package/docs/ko/dictionary/content_file.md +51 -1
- package/docs/ko/intlayer_with_nextjs_no_locale_path.md +3 -2
- package/docs/ko/mcp_server.md +31 -18
- package/docs/ko/plugins/sync-po.md +333 -0
- package/docs/nl/configuration.md +16 -12
- package/docs/pl/benchmark/index.md +0 -3
- package/docs/pl/benchmark/nextjs.md +15 -6
- package/docs/pl/benchmark/solid.md +155 -0
- package/docs/pl/benchmark/svelte.md +148 -0
- package/docs/pl/benchmark/tanstack.md +12 -3
- package/docs/pl/benchmark/vue.md +160 -0
- package/docs/pl/configuration.md +16 -12
- package/docs/pl/dictionary/content_file.md +51 -1
- package/docs/pl/mcp_server.md +30 -17
- package/docs/pl/plugins/sync-po.md +333 -0
- package/docs/pt/benchmark/index.md +0 -3
- package/docs/pt/benchmark/nextjs.md +16 -7
- package/docs/pt/benchmark/solid.md +155 -0
- package/docs/pt/benchmark/svelte.md +148 -0
- package/docs/pt/benchmark/tanstack.md +13 -4
- package/docs/pt/benchmark/vue.md +160 -0
- package/docs/pt/configuration.md +16 -12
- package/docs/pt/dictionary/content_file.md +51 -1
- package/docs/pt/mcp_server.md +30 -17
- package/docs/pt/plugins/sync-po.md +333 -0
- package/docs/ru/benchmark/nextjs.md +15 -6
- package/docs/ru/benchmark/solid.md +155 -0
- package/docs/ru/benchmark/svelte.md +148 -0
- package/docs/ru/benchmark/tanstack.md +12 -3
- package/docs/ru/benchmark/vue.md +160 -0
- package/docs/ru/configuration.md +16 -12
- package/docs/ru/dictionary/content_file.md +52 -2
- package/docs/ru/mcp_server.md +30 -17
- package/docs/ru/plugins/sync-po.md +333 -0
- package/docs/tr/benchmark/index.md +0 -3
- package/docs/tr/benchmark/nextjs.md +15 -6
- package/docs/tr/benchmark/solid.md +155 -0
- package/docs/tr/benchmark/svelte.md +148 -0
- package/docs/tr/benchmark/tanstack.md +12 -3
- package/docs/tr/benchmark/vue.md +160 -0
- package/docs/tr/configuration.md +16 -12
- package/docs/tr/dictionary/content_file.md +51 -1
- package/docs/tr/mcp_server.md +31 -18
- package/docs/tr/plugins/sync-po.md +333 -0
- package/docs/uk/benchmark/nextjs.md +15 -6
- package/docs/uk/benchmark/solid.md +155 -0
- package/docs/uk/benchmark/svelte.md +148 -0
- package/docs/uk/benchmark/tanstack.md +12 -3
- package/docs/uk/benchmark/vue.md +160 -0
- package/docs/uk/configuration.md +16 -12
- package/docs/uk/dictionary/content_file.md +51 -1
- package/docs/uk/mcp_server.md +29 -16
- package/docs/uk/plugins/sync-po.md +333 -0
- package/docs/ur/configuration.md +16 -12
- package/docs/vi/benchmark/index.md +0 -3
- package/docs/vi/benchmark/nextjs.md +15 -6
- package/docs/vi/benchmark/solid.md +155 -0
- package/docs/vi/benchmark/svelte.md +148 -0
- package/docs/vi/benchmark/tanstack.md +12 -3
- package/docs/vi/benchmark/vue.md +160 -0
- package/docs/vi/configuration.md +16 -12
- package/docs/vi/dictionary/content_file.md +51 -1
- package/docs/vi/intlayer_with_nextjs_15.md +10 -57
- package/docs/vi/mcp_server.md +30 -17
- package/docs/vi/plugins/sync-po.md +333 -0
- package/docs/zh/benchmark/nextjs.md +15 -6
- package/docs/zh/benchmark/solid.md +155 -0
- package/docs/zh/benchmark/svelte.md +148 -0
- package/docs/zh/benchmark/tanstack.md +12 -3
- package/docs/zh/benchmark/vue.md +160 -0
- package/docs/zh/configuration.md +16 -12
- package/docs/zh/dictionary/content_file.md +51 -3
- package/docs/zh/mcp_server.md +31 -18
- package/docs/zh/plugins/sync-po.md +333 -0
- package/frequent_questions/ar/intlayerNode.md +3 -3
- package/frequent_questions/de/intlayerNode.md +3 -3
- package/frequent_questions/en/intlayerNode.md +3 -3
- package/frequent_questions/en-GB/intlayerNode.md +3 -3
- package/frequent_questions/es/intlayerNode.md +3 -3
- package/frequent_questions/fr/intlayerNode.md +3 -3
- package/frequent_questions/hi/intlayerNode.md +3 -3
- package/frequent_questions/id/intlayerNode.md +3 -3
- package/frequent_questions/it/intlayerNode.md +3 -3
- package/frequent_questions/ja/intlayerNode.md +3 -3
- package/frequent_questions/ko/intlayerNode.md +3 -3
- package/frequent_questions/pl/intlayerNode.md +3 -3
- package/frequent_questions/pt/intlayerNode.md +3 -3
- package/frequent_questions/ru/intlayerNode.md +3 -3
- package/frequent_questions/tr/intlayerNode.md +3 -3
- package/frequent_questions/uk/intlayerNode.md +3 -3
- package/frequent_questions/vi/intlayerNode.md +3 -3
- package/frequent_questions/zh/intlayerNode.md +3 -3
- package/package.json +8 -8
- package/src/generated/docs.entry.ts +20 -0
package/docs/en-GB/mcp_server.md
CHANGED
|
@@ -23,7 +23,7 @@ history:
|
|
|
23
23
|
changes: "Add set up of Claude Desktop"
|
|
24
24
|
- version: 5.5.12
|
|
25
25
|
date: 2025-07-10
|
|
26
|
-
changes: "Add
|
|
26
|
+
changes: "Add Streamable HTTP transport and distant server"
|
|
27
27
|
- version: 5.5.10
|
|
28
28
|
date: 2025-06-29
|
|
29
29
|
changes: "Initialise history"
|
|
@@ -51,12 +51,12 @@ By enabling the Intlayer MCP Server in your IDE, you unlock:
|
|
|
51
51
|
|
|
52
52
|
> View the full list of commands and options in the [Intlayer CLI documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/cli/index.md).
|
|
53
53
|
|
|
54
|
-
## Local server (stdio) vs Remote server (
|
|
54
|
+
## Local server (stdio) vs Remote server (Streamable HTTP)
|
|
55
55
|
|
|
56
56
|
The MCP server can be used in two ways:
|
|
57
57
|
|
|
58
58
|
- Local server (stdio)
|
|
59
|
-
- Remote server (
|
|
59
|
+
- Remote server (Streamable HTTP)
|
|
60
60
|
|
|
61
61
|
### Local server (stdio) (recommended)
|
|
62
62
|
|
|
@@ -64,9 +64,9 @@ Intlayer provides an NPM package that can be installed locally on your machine.
|
|
|
64
64
|
|
|
65
65
|
This server is the recommended way to use the MCP server, as it integrates all the features of the MCP server, including the CLI tools.
|
|
66
66
|
|
|
67
|
-
### Remote server (
|
|
67
|
+
### Remote server (Streamable HTTP)
|
|
68
68
|
|
|
69
|
-
The MCP server can also be used remotely, using the
|
|
69
|
+
The MCP server can also be used remotely, using the Streamable HTTP transport method. This server is hosted by Intlayer and is available at https://mcp.intlayer.org. This server can be accessed publicly, without any authentication, and is free to use.
|
|
70
70
|
|
|
71
71
|
Note that the remote server does not integrate CLI tools, AI autocompletion, etc. The remote server is only for interaction with the documentation to assist your AI assistant with the Intlayer ecosystem.
|
|
72
72
|
|
|
@@ -97,7 +97,7 @@ bun x intlayer init mcp
|
|
|
97
97
|
This command will:
|
|
98
98
|
|
|
99
99
|
1. Ask you which platform you are using (Cursor, VS Code, Claude Desktop, etc.).
|
|
100
|
-
2. Ask you which transport method you want to use (Local server (stdio) or Remote server (
|
|
100
|
+
2. Ask you which transport method you want to use (Local server (stdio) or Remote server (Streamable HTTP)).
|
|
101
101
|
3. Automatically update your configuration file (e.g., `.cursor/mcp.json`, `.vscode/mcp.json`, or the global Claude Desktop config).
|
|
102
102
|
|
|
103
103
|
---
|
|
@@ -107,7 +107,7 @@ This command will:
|
|
|
107
107
|
1. Open the Command Palette (Ctrl+Shift+P or Cmd+Shift+P).
|
|
108
108
|
2. Type `Intlayer: Setup AI Agent Skills`
|
|
109
109
|
3. Pick the platform you use (e.g. `VS Code`, `Cursor`, `Windsurf`, `OpenCode`, `Claude Code`, `GitHub Copilot Workspace`, etc.).
|
|
110
|
-
4. Pick the MCP to install (stdio,
|
|
110
|
+
4. Pick the MCP to install (stdio, Streamable HTTP)
|
|
111
111
|
5. Press Enter.
|
|
112
112
|
|
|
113
113
|
---
|
|
@@ -131,16 +131,16 @@ In your project root, add the following `.cursor/mcp.json` configuration file:
|
|
|
131
131
|
}
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
### Remote server (
|
|
134
|
+
### Remote server (Streamable HTTP)
|
|
135
135
|
|
|
136
|
-
For connecting to a remote Intlayer MCP server using Server-Sent Events (
|
|
136
|
+
For connecting to a remote Intlayer MCP server using Server-Sent Events (Streamable HTTP), you can configure your MCP client to connect to the hosted service.
|
|
137
137
|
|
|
138
138
|
```json fileName=".cursor/mcp.json"
|
|
139
139
|
{
|
|
140
140
|
"mcpServers": {
|
|
141
|
-
"intlayer": {
|
|
142
|
-
"
|
|
143
|
-
"
|
|
141
|
+
"intlayer-sse": {
|
|
142
|
+
"command": "npx",
|
|
143
|
+
"args": ["-y", "mcp-remote@latest", "https://mcp.intlayer.org"]
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
}
|
|
@@ -172,16 +172,16 @@ Create a `.vscode/mcp.json` file in your project root:
|
|
|
172
172
|
}
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
-
### Remote server (
|
|
175
|
+
### Remote server (Streamable HTTP)
|
|
176
176
|
|
|
177
|
-
For connecting to a remote Intlayer MCP server using Server-Sent Events (
|
|
177
|
+
For connecting to a remote Intlayer MCP server using Server-Sent Events (Streamable HTTP), you can configure your MCP client to connect to the hosted service.
|
|
178
178
|
|
|
179
179
|
```json fileName=".vscode/mcp.json"
|
|
180
180
|
{
|
|
181
181
|
"servers": {
|
|
182
|
-
"intlayer": {
|
|
183
|
-
"
|
|
184
|
-
"
|
|
182
|
+
"intlayer-sse": {
|
|
183
|
+
"command": "npx",
|
|
184
|
+
"args": ["-y", "mcp-remote@latest", "https://mcp.intlayer.org"]
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
}
|
|
@@ -191,7 +191,7 @@ For connecting to a remote Intlayer MCP server using Server-Sent Events (SSE), y
|
|
|
191
191
|
|
|
192
192
|
## Set Up in ChatGPT
|
|
193
193
|
|
|
194
|
-
### Remote server (
|
|
194
|
+
### Remote server (Streamable HTTP)
|
|
195
195
|
|
|
196
196
|
Follow the [official documentation](https://platform.openai.com/docs/mcp#test-and-connect-your-mcp-server) to configure the MCP server in ChatGPT.
|
|
197
197
|
|
|
@@ -232,6 +232,19 @@ Path of the config file:
|
|
|
232
232
|
}
|
|
233
233
|
```
|
|
234
234
|
|
|
235
|
+
### Remote server (Streamable HTTP)
|
|
236
|
+
|
|
237
|
+
```json fileName="claude_desktop_config.json"
|
|
238
|
+
{
|
|
239
|
+
"mcpServers": {
|
|
240
|
+
"intlayer-sse": {
|
|
241
|
+
"command": "npx",
|
|
242
|
+
"args": ["-y", "mcp-remote@latest", "https://mcp.intlayer.org"]
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
235
248
|
---
|
|
236
249
|
|
|
237
250
|
## Using the MCP Server via CLI
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-05-10
|
|
3
|
+
updatedAt: 2026-05-10
|
|
4
|
+
title: Sync PO plugin
|
|
5
|
+
description: Synchronise Intlayer dictionaries with Gettext PO files. Keep your existing i18n while using Intlayer to manage, translate, and test your messages.
|
|
6
|
+
keywords:
|
|
7
|
+
- Intlayer
|
|
8
|
+
- Sync PO
|
|
9
|
+
- Gettext
|
|
10
|
+
- i18n
|
|
11
|
+
- translations
|
|
12
|
+
slugs:
|
|
13
|
+
- doc
|
|
14
|
+
- plugin
|
|
15
|
+
- sync-po
|
|
16
|
+
youtubeVideo: https://www.youtube.com/watch?v=MpGMxniDHNg
|
|
17
|
+
history:
|
|
18
|
+
- version: 8.9.4
|
|
19
|
+
date: 2026-05-10
|
|
20
|
+
changes: "Initial Sync PO plugin documentation"
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Sync PO (i18n bridges) - Sync PO with ICU / i18next support
|
|
24
|
+
|
|
25
|
+
Use Intlayer as an add‑on to your existing i18n stack. This plugin keeps your Gettext PO messages in sync with Intlayer dictionaries so you can:
|
|
26
|
+
|
|
27
|
+
- Keep your existing PO-based translation workflow.
|
|
28
|
+
- Manage and translate your messages with Intlayer (CLI, CI, providers, CMS), without refactoring your app.
|
|
29
|
+
- Ship tutorials and SEO content targeting each ecosystem, while suggesting Intlayer as the PO management layer.
|
|
30
|
+
|
|
31
|
+
Notes and current scope:
|
|
32
|
+
|
|
33
|
+
- Externalisation to the CMS works for translations and classic text.
|
|
34
|
+
- No support yet for insertions, plurals/ICU, or advanced runtime features of other libraries within the PO entries themselves.
|
|
35
|
+
- The visual editor is not supported yet for third‑party i18n outputs.
|
|
36
|
+
|
|
37
|
+
### When to use this plugin
|
|
38
|
+
|
|
39
|
+
- You already use Gettext PO files for your translations.
|
|
40
|
+
- You want AI‑assisted fill, test in CI, and content ops without changing your rendering runtime.
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pnpm add -D @intlayer/sync-po-plugin
|
|
46
|
+
# or
|
|
47
|
+
npm i -D @intlayer/sync-po-plugin
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Plugins
|
|
51
|
+
|
|
52
|
+
This package provides two plugins:
|
|
53
|
+
|
|
54
|
+
- `loadPO`: Load PO files into Intlayer dictionaries.
|
|
55
|
+
- This plugin is used to load PO files from a source and will be loaded into Intlayer dictionaries. It can scan all the codebase and search for specific PO files.
|
|
56
|
+
This plugin can be used
|
|
57
|
+
- if you use an i18n library that imposes a specific location for your PO files to be loaded, but you want to place your content declaration where you want in your code base.
|
|
58
|
+
- It can also be used if you want to fetch your messages from a remote source (ex: a CMS, an API, etc.) and store your messages in PO files.
|
|
59
|
+
|
|
60
|
+
> Under the bonnet, this plugin will scan all the codebase and search for specific PO files and load them into Intlayer dictionaries.
|
|
61
|
+
> Note that this plugin will not write the output and translations back to the PO files.
|
|
62
|
+
|
|
63
|
+
- `syncPO`: Synchronise PO files with Intlayer dictionaries.
|
|
64
|
+
- This plugin is used to synchronise PO files with Intlayer dictionaries. It can scan the given location and load the PO that match the pattern for specific PO files. This plugin is useful if you want to get the benefits of Intlayer while using another i18n library.
|
|
65
|
+
|
|
66
|
+
## Using both plugins
|
|
67
|
+
|
|
68
|
+
```ts fileName="intlayer.config.ts"
|
|
69
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
70
|
+
import { loadPO, syncPO } from "@intlayer/sync-po-plugin";
|
|
71
|
+
|
|
72
|
+
const config: IntlayerConfig = {
|
|
73
|
+
internationalization: {
|
|
74
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
75
|
+
defaultLocale: Locales.ENGLISH,
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
// Keep your current PO files in sync with Intlayer dictionaries
|
|
79
|
+
plugins: [
|
|
80
|
+
/**
|
|
81
|
+
* Will load all the PO files in the src that match the pattern {key}.i18n.po
|
|
82
|
+
*/
|
|
83
|
+
loadPO({
|
|
84
|
+
source: ({ key }) => `./src/**/${key}.i18n.po`,
|
|
85
|
+
locale: Locales.ENGLISH,
|
|
86
|
+
priority: 1, // Ensures these PO files take precedence over files at `./locales/en/${key}.po`
|
|
87
|
+
}),
|
|
88
|
+
/**
|
|
89
|
+
* Will load, and write the output and translations back to the PO files in the locales directory
|
|
90
|
+
*/
|
|
91
|
+
syncPO({
|
|
92
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.po`,
|
|
93
|
+
priority: 0,
|
|
94
|
+
}),
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export default config;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## `syncPO` plugin
|
|
102
|
+
|
|
103
|
+
### Quick start
|
|
104
|
+
|
|
105
|
+
Add the plugin to your `intlayer.config.ts` and point it at your existing PO structure.
|
|
106
|
+
|
|
107
|
+
```ts fileName="intlayer.config.ts"
|
|
108
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
109
|
+
import { syncPO } from "@intlayer/sync-po-plugin";
|
|
110
|
+
|
|
111
|
+
const config: IntlayerConfig = {
|
|
112
|
+
internationalization: {
|
|
113
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
114
|
+
defaultLocale: Locales.ENGLISH,
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// Keep your current PO files in sync with Intlayer dictionaries
|
|
118
|
+
plugins: [
|
|
119
|
+
syncPO({
|
|
120
|
+
// Per-locale, per-namespace layout
|
|
121
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.po`,
|
|
122
|
+
}),
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export default config;
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Alternative: single file per locale:
|
|
130
|
+
|
|
131
|
+
```ts fileName="intlayer.config.ts"
|
|
132
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
133
|
+
import { syncPO } from "@intlayer/sync-po-plugin";
|
|
134
|
+
|
|
135
|
+
const config: IntlayerConfig = {
|
|
136
|
+
internationalization: {
|
|
137
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
138
|
+
defaultLocale: Locales.ENGLISH,
|
|
139
|
+
},
|
|
140
|
+
plugins: [
|
|
141
|
+
syncPO({
|
|
142
|
+
source: ({ locale }) => `./locales/${locale}.po`,
|
|
143
|
+
}),
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export default config;
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### How it works
|
|
151
|
+
|
|
152
|
+
- Read: the plugin discovers PO files from your `source` builder and loads them as Intlayer dictionaries.
|
|
153
|
+
- Write: after builds and fills, it writes localised PO back to the same paths (with proper Gettext headers).
|
|
154
|
+
- Auto‑fill: the plugin declares an `autoFill` path for each dictionary. Running `intlayer fill` updates only missing translations in your PO files by default.
|
|
155
|
+
|
|
156
|
+
API:
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
syncPO({
|
|
160
|
+
source: ({ key, locale }) => string, // required
|
|
161
|
+
location?: string, // optional label, default: "sync-po::path/to/source"
|
|
162
|
+
priority?: number, // optional priority for conflict resolution, default: 0
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Multiple PO sources and priority
|
|
167
|
+
|
|
168
|
+
You can add multiple `syncPO` plugins to synchronise different PO sources. This is useful when you have multiple translation sources or different PO structures in your project.
|
|
169
|
+
|
|
170
|
+
#### Priority system
|
|
171
|
+
|
|
172
|
+
When multiple plugins target the same dictionary key, the `priority` parameter determines which plugin takes precedence:
|
|
173
|
+
|
|
174
|
+
- Higher priority numbers win over lower ones
|
|
175
|
+
- Default priority of `.content` files is `0`
|
|
176
|
+
- Default priority of plugins is `0`
|
|
177
|
+
- Plugins with the same priority are processed in the order they appear in the configuration
|
|
178
|
+
|
|
179
|
+
```ts fileName="intlayer.config.ts"
|
|
180
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
181
|
+
import { syncPO } from "@intlayer/sync-po-plugin";
|
|
182
|
+
|
|
183
|
+
const config: IntlayerConfig = {
|
|
184
|
+
internationalization: {
|
|
185
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
186
|
+
defaultLocale: Locales.ENGLISH,
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
plugins: [
|
|
190
|
+
// Primary PO source (highest priority)
|
|
191
|
+
syncPO({
|
|
192
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.po`,
|
|
193
|
+
location: "main-translations",
|
|
194
|
+
priority: 10,
|
|
195
|
+
}),
|
|
196
|
+
|
|
197
|
+
// Fallback PO source (lower priority)
|
|
198
|
+
syncPO({
|
|
199
|
+
source: ({ locale }) => `./fallback-locales/${locale}.po`,
|
|
200
|
+
location: "fallback-translations",
|
|
201
|
+
priority: 5,
|
|
202
|
+
}),
|
|
203
|
+
|
|
204
|
+
// Legacy PO source (lowest priority)
|
|
205
|
+
syncPO({
|
|
206
|
+
source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.po`,
|
|
207
|
+
location: "legacy-translations",
|
|
208
|
+
priority: 1,
|
|
209
|
+
}),
|
|
210
|
+
],
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export default config;
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Load PO plugin
|
|
217
|
+
|
|
218
|
+
### Quick start
|
|
219
|
+
|
|
220
|
+
Add the plugin to your `intlayer.config.ts` to ingest existing PO files as Intlayer dictionaries. This plugin is read‑only (no writes to disk):
|
|
221
|
+
|
|
222
|
+
```ts fileName="intlayer.config.ts"
|
|
223
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
224
|
+
import { loadPO } from "@intlayer/sync-po-plugin";
|
|
225
|
+
|
|
226
|
+
const config: IntlayerConfig = {
|
|
227
|
+
internationalization: {
|
|
228
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
229
|
+
defaultLocale: Locales.ENGLISH,
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
plugins: [
|
|
233
|
+
// Ingest PO messages located anywhere in your source tree
|
|
234
|
+
loadPO({
|
|
235
|
+
source: ({ key }) => `./src/**/${key}.i18n.po`,
|
|
236
|
+
// Load a single locale per plugin instance (defaults to the config defaultLocale)
|
|
237
|
+
locale: Locales.ENGLISH,
|
|
238
|
+
priority: 0,
|
|
239
|
+
}),
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
export default config;
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Alternative: per‑locale layout, still read‑only (only the selected locale is loaded):
|
|
247
|
+
|
|
248
|
+
```ts fileName="intlayer.config.ts"
|
|
249
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
250
|
+
import { loadPO } from "@intlayer/sync-po-plugin";
|
|
251
|
+
|
|
252
|
+
const config: IntlayerConfig = {
|
|
253
|
+
internationalization: {
|
|
254
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
255
|
+
defaultLocale: Locales.ENGLISH,
|
|
256
|
+
},
|
|
257
|
+
plugins: [
|
|
258
|
+
loadPO({
|
|
259
|
+
// Only files for Locales.FRENCH will be loaded from this pattern
|
|
260
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.po`,
|
|
261
|
+
locale: Locales.FRENCH,
|
|
262
|
+
}),
|
|
263
|
+
],
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
export default config;
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### How it works
|
|
270
|
+
|
|
271
|
+
- Discover: builds a glob from your `source` builder and collects matching PO files.
|
|
272
|
+
- Ingest: loads each PO file as an Intlayer dictionary with the provided `locale`.
|
|
273
|
+
- Read‑only: does not write or format output files; use `syncPO` if you need round‑trip sync.
|
|
274
|
+
- Auto‑fill ready: defines a `fill` path so `intlayer content fill` can populate missing keys.
|
|
275
|
+
|
|
276
|
+
### API
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
loadPO({
|
|
280
|
+
// Build paths to your PO. `locale` is optional if your structure has no locale segment
|
|
281
|
+
source: ({ key, locale }) => string,
|
|
282
|
+
|
|
283
|
+
// Target locale for the dictionaries loaded by this plugin instance
|
|
284
|
+
// Defaults to configuration.internationalization.defaultLocale
|
|
285
|
+
locale?: Locale,
|
|
286
|
+
|
|
287
|
+
// Optional label to identify the source
|
|
288
|
+
location?: string, // default: "plugin"
|
|
289
|
+
|
|
290
|
+
// Priority used for conflict resolution against other sources
|
|
291
|
+
priority?: number, // default: 0
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Behaviour and conventions
|
|
296
|
+
|
|
297
|
+
- If your `source` mask includes a locale placeholder, only files for the selected `locale` are ingested.
|
|
298
|
+
- If there is no `{key}` segment in your mask, the dictionary key is "index".
|
|
299
|
+
- Keys are derived from file paths by substituting the `{key}` placeholder in your `source` builder.
|
|
300
|
+
- The plugin only uses discovered files and does not fabricate missing locales or keys.
|
|
301
|
+
- The `fill` path is inferred from your `source` and used to update missing values via CLI when you opt‑in.
|
|
302
|
+
|
|
303
|
+
## Conflict resolution
|
|
304
|
+
|
|
305
|
+
When the same translation key exists in multiple PO sources:
|
|
306
|
+
|
|
307
|
+
1. The plugin with the highest priority determines the final value
|
|
308
|
+
2. Lower priority sources are used as fallbacks for missing keys
|
|
309
|
+
3. This allows you to maintain legacy translations while gradually migrating to new structures
|
|
310
|
+
|
|
311
|
+
## CLI
|
|
312
|
+
|
|
313
|
+
The synchronised PO files will be considered as other `.content` files. That means, all intlayer commands will be available for the synchronised PO files. Including:
|
|
314
|
+
|
|
315
|
+
- `intlayer content test` to test if there are missing translations
|
|
316
|
+
- `intlayer content list` to list the synchronised PO files
|
|
317
|
+
- `intlayer content fill` to fill the missing translations
|
|
318
|
+
- `intlayer content push` to push the synchronised PO files
|
|
319
|
+
- `intlayer content pull` to pull the synchronised PO files
|
|
320
|
+
|
|
321
|
+
See [Intlayer CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/cli/index.md) for more details.
|
|
322
|
+
|
|
323
|
+
## Limitations (current)
|
|
324
|
+
|
|
325
|
+
- No insertions or plurals/ICU support when targeting third‑party libraries.
|
|
326
|
+
- Visual editor is not available for non‑Intlayer runtimes yet.
|
|
327
|
+
- PO synchronisation only; non‑PO catalog formats are not supported.
|
|
328
|
+
|
|
329
|
+
## Why this matters
|
|
330
|
+
|
|
331
|
+
- We can recommend established i18n solutions and position Intlayer as an add‑on.
|
|
332
|
+
- We leverage their SEO/keywords with tutorials that end by suggesting Intlayer to manage PO.
|
|
333
|
+
- Expands the addressable audience from “new projects” to “any team already using i18n”.
|
|
@@ -30,6 +30,3 @@ A continuación encontrarás los informes detallados y la documentación técnic
|
|
|
30
30
|
- [**Vue Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/vue.md)
|
|
31
31
|
- [**Solid Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/solid.md)
|
|
32
32
|
- [**Svelte Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/svelte.md)
|
|
33
|
-
- [**Vue Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/vue.md)
|
|
34
|
-
- [**Solid Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/solid.md)
|
|
35
|
-
- [**Svelte Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/svelte.md)
|
|
@@ -61,6 +61,13 @@ Debido a que el problema es difícil, existen muchas soluciones: algunas enfocad
|
|
|
61
61
|
|
|
62
62
|
Intlayer intenta optimizar en todas estas dimensiones.
|
|
63
63
|
|
|
64
|
+
## TL;DR
|
|
65
|
+
|
|
66
|
+
- **Intlayer** y **next-translate**: Las mejores opciones para el rendimiento en Next.js, ofreciendo la menor huella y el mejor soporte para renderizado estático.
|
|
67
|
+
- **next-intl**: La opción más de moda pero pesada y compleja de optimizar para aplicaciones grandes.
|
|
68
|
+
- **next-i18next**: Popular y rica en plugins, pero conlleva un peso de bundle significativo (~3× Intlayer).
|
|
69
|
+
- **Evitar**: **gt-next** y **lingo.dev** debido a graves problemas de rendimiento, bloqueo del proveedor (vendor lock-in) y errores que rompen la compilación.
|
|
70
|
+
|
|
64
71
|
## Pon a prueba tu aplicación
|
|
65
72
|
|
|
66
73
|
Para sacar a la luz estos problemas, he creado un escáner gratuito que puedes probar [aquí](https://intlayer.org/i18n-seo-scanner).
|
|
@@ -99,14 +106,14 @@ Finalmente, `Intlayer` aplica una optimización en tiempo de compilación para q
|
|
|
99
106
|
Para este benchmark, comparamos las siguientes librerías:
|
|
100
107
|
|
|
101
108
|
- `Base App` (Sin librería i18n)
|
|
102
|
-
- `next-intlayer` (v8.7.
|
|
109
|
+
- `next-intlayer` (v8.7.12)
|
|
103
110
|
- `next-i18next` (v16.0.5)
|
|
104
111
|
- `next-intl` (v4.9.1)
|
|
105
112
|
- `@lingui/core` (v5.3.0)
|
|
106
113
|
- `next-translate` (v3.1.2)
|
|
107
114
|
- `next-international` (v1.3.1)
|
|
108
115
|
- `@inlang/paraglide-js` (v2.15.1)
|
|
109
|
-
-
|
|
116
|
+
- `@tolgee/react` (v7.0.0)
|
|
110
117
|
- `@lingo.dev/compiler` (v0.4.0)
|
|
111
118
|
- `wuchale` (v0.22.11)
|
|
112
119
|
- `gt-next` (v6.16.5)
|
|
@@ -161,10 +168,10 @@ Problemas encontrados:
|
|
|
161
168
|
|
|
162
169
|
**(General Translation)** (`gt-next@6.16.5`):
|
|
163
170
|
|
|
164
|
-
- Para una aplicación de 110kb, `gt-
|
|
171
|
+
- Para una aplicación de 110kb, `gt-next` añade más de 440kb extra.
|
|
165
172
|
- `Quota Exceeded, please upgrade your plan` en la primerísima compilación con General Translation.
|
|
166
173
|
- Las traducciones no se renderizan; obtengo el error `Error: <T> used on the client-side outside of <GTProvider>`, lo que parece ser un bug de la librería.
|
|
167
|
-
- Mientras implementaba **gt-
|
|
174
|
+
- Mientras implementaba **gt-next**, también encontré un [problema](https://github.com/generaltranslation/gt/issues/1210#event-24510646961) con la librería: `does not provide an export named 'printAST' - @formatjs/icu-messageformat-parser`, que hacía que la aplicación se rompiera. Tras informar de este problema, el mantenedor lo solucionó en 24 horas.
|
|
168
175
|
- La librería bloquea el renderizado estático de las páginas de Next.js.
|
|
169
176
|
|
|
170
177
|
**(Lingo.dev)** (`@lingo.dev/compiler@0.4.0`):
|
|
@@ -185,9 +192,11 @@ La idea detrás de `Wuchale` es interesante pero aún no es viable. Experimenté
|
|
|
185
192
|
`Paraglide` ofrece un enfoque innovador y bien pensado. Aun así, en este benchmark, el tree-shaking que su empresa anuncia no funcionó para mis configuraciones de Next.js o TanStack Start. El flujo de trabajo y la DX son más complejos que otras opciones. Personalmente, no me gusta tener que regenerar archivos JS antes de cada push, lo que crea un riesgo constante de conflictos de fusión a través de las PR. La herramienta también parece más enfocada en Vite que en Next.js.
|
|
186
193
|
Finalmente, en comparación con otras soluciones, Paraglide no usa un almacén (ej. contexto de React) para recuperar el idioma actual y renderizar el contenido. Por cada nodo analizado, solicita el idioma al localStorage / cookie, etc. Esto provoca la ejecución de lógica innecesaria que afecta a la reactividad del componente.
|
|
187
194
|
|
|
195
|
+
> Nota sobre paraglide: la solución inyecta código en tu base de código para importar, como resultado la métrica 'tamaño de la lib' en el informe del benchmark es casi 0. La generación de código es algo bueno, porque la función utilizada incluirá solo la lógica necesaria (prefijo total vs sin prefijo, cookie vs almacenamiento, etc.). En comparación, Intlayer realiza este filtrado mediante inyecciones de variables de entorno en la compilación para forzar al bundler a aplicar tree-shaking al contenido según la lógica. Gracias a esto, paraglide e intlayer terminan siendo soluciones de 6 a 10 veces más ligeras que i18next o next-intl.
|
|
196
|
+
|
|
188
197
|
### 3 — Soluciones aceptables
|
|
189
198
|
|
|
190
|
-
**(Tolgee)** (
|
|
199
|
+
**(Tolgee)** (`@tolgee/react@7.0.0`):
|
|
191
200
|
|
|
192
201
|
`Tolgee` aborda muchos de los problemas mencionados anteriormente. Me resultó más difícil de adoptar que herramientas similares. No proporciona seguridad de tipos (type safety), lo que también dificulta detectar claves faltantes en tiempo de compilación. Tuve que envolver las funciones de Tolgee con las mías propias para añadir la detección de claves faltantes.
|
|
193
202
|
|
|
@@ -215,7 +224,7 @@ A menudo se elogia a `Lingui`. Personalmente, encontré el flujo de trabajo `lin
|
|
|
215
224
|
|
|
216
225
|
`next-translate` es mi recomendación principal si te gusta una API de estilo `t()`. Es elegante a través de `next-translate-plugin`, cargando namespaces mediante `getStaticProps` con un cargador de Webpack / Turbopack. También es la opción más ligera aquí (~2.5kb). Para la segmentación por espacios de nombres, definirnamespaces por página o ruta en la configuración está bien pensado y es más fácil de mantener que las principales alternativas como **next-intl** o **next-i18next**. En la versión `3.1.2`, noté que el renderizado estático no funcionaba; Next.js recurría al renderizado dinámico.
|
|
217
226
|
|
|
218
|
-
**(Intlayer)** (`next-intlayer@8.7.
|
|
227
|
+
**(Intlayer)** (`next-intlayer@8.7.12`):
|
|
219
228
|
|
|
220
229
|
No seré yo quien juzgue personalmente a `next-intlayer` por objetividad, ya que es mi propia solución.
|
|
221
230
|
|