@inlang/paraglide-js 1.3.2 → 1.3.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 +79 -65
- package/dist/index.js +13 -9
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# Simple, adaptable, and tiny i18n library for JS
|
|
6
6
|
|
|
7
|
-
Get started
|
|
7
|
+
Get started with:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npx @inlang/paraglide-js@latest init
|
|
@@ -29,7 +29,7 @@ Treeshaking gives us superpowers. With it, each page of your app only loads the
|
|
|
29
29
|
|
|
30
30
|
### 1. Initialize paraglide-js
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Initialize paraglide-js whith:
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
35
|
npx @inlang/paraglide-js@latest init
|
|
@@ -37,13 +37,13 @@ npx @inlang/paraglide-js@latest init
|
|
|
37
37
|
|
|
38
38
|
This will:
|
|
39
39
|
|
|
40
|
-
1. Install
|
|
41
|
-
2.
|
|
42
|
-
3. Set up
|
|
40
|
+
1. Install necessary dependencies
|
|
41
|
+
2. Add the Paraglide compiler to your `build` script
|
|
42
|
+
3. Set up configuration files
|
|
43
43
|
|
|
44
44
|
### 2. Set up an adapter (optional)
|
|
45
45
|
|
|
46
|
-
Adapters are framework
|
|
46
|
+
Adapters are framework-integrations for Paraglide. If you are using a framework, using an adapter is recommended , but not required.
|
|
47
47
|
|
|
48
48
|
<doc-links>
|
|
49
49
|
<doc-link title="Adapter for NextJS" icon="tabler:brand-nextjs" href="https://inlang.com/m/osslbuzt/library-inlang-paraglideJsAdapterNextJs" description="Go to Library"></doc-link>
|
|
@@ -57,36 +57,34 @@ Adapters are framework specific integrations for Paraglide. If you are using a f
|
|
|
57
57
|
# Usage
|
|
58
58
|
|
|
59
59
|
Running your `build` script will generate a `src/paraglide` folder. This folder contains all the code that you need to use paraglide-js.
|
|
60
|
-
Throughout this guide, you will see imports from `./paraglide/*`. These are all to this folder.
|
|
61
60
|
|
|
62
|
-
> Tip: If you are using a bundler, you can set up an alias to `./src/paraglide` to make the imports shorter.
|
|
61
|
+
> Tip: If you are using a bundler, you can set up an alias to `./src/paraglide` to make the imports shorter.
|
|
62
|
+
|
|
63
|
+
## Adding Messages
|
|
64
|
+
|
|
65
|
+
By default, paraglide expects your messages to be in `messages/{lang}.json`.
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"hello": "Hello world!"
|
|
69
|
+
"loginHeader": "Hello {name}, please login to continue."
|
|
70
|
+
}
|
|
71
|
+
```
|
|
63
72
|
|
|
64
73
|
## Using Messages
|
|
65
74
|
|
|
66
|
-
|
|
75
|
+
You can import messages with `import * as m from "./paraglide/messages"`. Don't worry, your bundler will only include the messages that you actually use.
|
|
67
76
|
|
|
68
77
|
```js
|
|
69
|
-
// m is a namespace that contains all messages of your project
|
|
70
|
-
// a bundler like rollup or webpack only bundles
|
|
71
|
-
// the messages that are used
|
|
72
78
|
import * as m from "./paraglide/messages.js"
|
|
73
79
|
import { setLanguageTag } from "./paraglide/runtime.js"
|
|
74
80
|
|
|
75
|
-
// use a message
|
|
76
81
|
m.hello() // Hello world!
|
|
77
|
-
|
|
78
|
-
// message with parameters
|
|
79
82
|
m.loginHeader({ name: "Samuel" }) // Hello Samuel, please login to continue.
|
|
80
|
-
|
|
81
|
-
// change the language
|
|
82
|
-
setLanguageTag("de")
|
|
83
|
-
|
|
84
|
-
m.loginHeader({ name: "Samuel" }) // Hallo Samuel, bitte melde dich an, um fortzufahren.
|
|
85
83
|
```
|
|
86
84
|
|
|
87
|
-
If you want to
|
|
85
|
+
If you want to choose between messages at runtime, you can create a record of messages and index into it.
|
|
88
86
|
|
|
89
|
-
```
|
|
87
|
+
```ts
|
|
90
88
|
import * as m from "./paraglide/messages.js"
|
|
91
89
|
|
|
92
90
|
const season = {
|
|
@@ -94,26 +92,34 @@ const season = {
|
|
|
94
92
|
summer: m.summer,
|
|
95
93
|
autumn: m.autumn,
|
|
96
94
|
winter: m.winter,
|
|
97
|
-
}
|
|
95
|
+
} as const;
|
|
98
96
|
|
|
99
97
|
const msg = season["spring"]() // Hello spring!
|
|
100
98
|
```
|
|
101
99
|
|
|
102
|
-
Paraglide JS provides several exports from `./paraglide/runtime.js`:
|
|
103
100
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
101
|
+
### (optional) Using the [Sherlock](https://inlang.com/m/r7kp499g/app-inlang-ideExtension) IDE Extension
|
|
102
|
+
|
|
103
|
+
[Sherlock](https://inlang.com/m/r7kp499g/app-inlang-ideExtension) integrates with paraglide to give you the optimal dev-experience.
|
|
104
|
+
|
|
105
|
+

|
|
106
|
+
|
|
107
|
+
## Adding Languages
|
|
108
|
+
|
|
109
|
+
You can declare which languages you support in `./project.inlang/settings.json` in the `languageTags` array.
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
// project.inlang/settings.json
|
|
113
|
+
{
|
|
114
|
+
"languageTags": ["en", "de"]
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Then create another `messages/{lang}.json` file and get translating!
|
|
113
119
|
|
|
114
120
|
## Setting the language
|
|
115
121
|
|
|
116
|
-
You can set the
|
|
122
|
+
You can set the [language tag](https://www.inlang.com/m/8y8sxj09/library-inlang-languageTag) by calling `setLanguageTag()`. Any subsequent calls to either `languageTag()` or a message function will use the new language tag.
|
|
117
123
|
|
|
118
124
|
```js
|
|
119
125
|
import { setLanguageTag } from "./paraglide/runtime.js"
|
|
@@ -126,22 +132,15 @@ setLanguageTag("en")
|
|
|
126
132
|
m.hello() // Hello world!
|
|
127
133
|
```
|
|
128
134
|
|
|
129
|
-
The [language tag](https://www.inlang.com/m/8y8sxj09/library-inlang-languageTag) is global, so you need to be careful with it on the server to make sure multiple requests don't interfere with each other.
|
|
130
|
-
|
|
131
|
-
## Adding Languages
|
|
135
|
+
The [language tag](https://www.inlang.com/m/8y8sxj09/library-inlang-languageTag) is global, so you need to be careful with it on the server to make sure multiple requests don't interfere with each other.
|
|
132
136
|
|
|
133
|
-
You
|
|
137
|
+
You will need to call `setLanguageTag` on both the server and the client, since they run in separate processes.
|
|
134
138
|
|
|
135
|
-
|
|
136
|
-
// project.inlang/settings.json
|
|
137
|
-
{
|
|
138
|
-
"languageTags": ["en", "de"]
|
|
139
|
-
}
|
|
140
|
-
```
|
|
139
|
+
## Reacting to language changes
|
|
141
140
|
|
|
142
|
-
|
|
141
|
+
Messages aren't reactive, so you will need to trigger a re-render when the language changes. You can register a callback using `onSetLanguageTag()`. It is called whenever the [language tag](https://www.inlang.com/m/8y8sxj09/library-inlang-languageTag) changes.
|
|
143
142
|
|
|
144
|
-
|
|
143
|
+
If you are using an adapter this is likely done for you.
|
|
145
144
|
|
|
146
145
|
```js
|
|
147
146
|
import { setLanguageTag, onSetLanguageTag } from "./paraglide/runtime.js"
|
|
@@ -158,36 +157,52 @@ setLanguageTag("en") // The language changed to en
|
|
|
158
157
|
There are a few things to know about `onSetLanguageTag()`:
|
|
159
158
|
|
|
160
159
|
- You can only register one listener. If you register a second listener it will throw an error.
|
|
161
|
-
-
|
|
160
|
+
- `setLanguageTag` shouldn't be used on the server.
|
|
161
|
+
|
|
162
|
+
## Getting a message in a specific language
|
|
162
163
|
|
|
163
|
-
|
|
164
|
+
You can import a message in a specific language from `paraglide/messages/{lang}.js`. This is great if you always need the same language in a given file.
|
|
164
165
|
|
|
165
|
-
|
|
166
|
+
```ts
|
|
167
|
+
import * as m from "./paraglide/messages/de.js"
|
|
168
|
+
m.hello() // Hallo Welt
|
|
169
|
+
```
|
|
166
170
|
|
|
167
|
-
|
|
168
|
-
second parameter.
|
|
171
|
+
If you want to force a language, but don't know ahead of time _which_ language you can pass the `languageTag` option as the second parameter to a message function. This is often needed on the server.
|
|
169
172
|
|
|
170
173
|
```js
|
|
171
174
|
import * as m from "./paraglide/messages.js"
|
|
172
175
|
const msg = m.hello({ name: "Samuel" }, { languageTag: "de" }) // Hallo Samuel!
|
|
173
176
|
```
|
|
174
177
|
|
|
178
|
+
## Lazy-Loading
|
|
179
|
+
|
|
180
|
+
Paraglide consciously discourages lazy-loading translations since it seriously hurts
|
|
181
|
+
your web-vitals. Learn more about why lazy-loading is bad & what to do instead in [this blog post](https://inlang.com/g/mqlyfa7l/guide-lorissigrist-dontlazyload).
|
|
182
|
+
|
|
183
|
+
If you _really_ want to do it anway, you can lazily import the language-specific message files. Be careful with this, as it's easy to accidenally break tree-shaking.
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
const lazyGerman = await import("./paraglide/messages/de.js")
|
|
187
|
+
```
|
|
188
|
+
|
|
175
189
|
## Usage with a Bundler
|
|
176
190
|
|
|
177
191
|
We provide bundler plugins to make it easier to use Paraglide with a bundler. If you
|
|
178
|
-
are using one
|
|
192
|
+
are using one we recommed using the corresponding plugin.
|
|
179
193
|
|
|
180
194
|
- [Rollup](https://github.com/opral/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-rollup)
|
|
181
195
|
- [Webpack](https://github.com/opral/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-webpack)
|
|
182
196
|
- [Vite](https://github.com/opral/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-vite)
|
|
183
197
|
|
|
184
|
-
These plugins make sure to
|
|
198
|
+
These plugins make sure to compile your messages whenever you build your project. If your bundler has a dev-server, like Vite, the plugin also makes sure to recompile whenever your messages change.
|
|
185
199
|
|
|
186
200
|
# Playground
|
|
187
201
|
|
|
188
202
|
You can find many examples for how to use paraglide on codesandbox, or in [our GitHub repository](https://github.com/opral/monorepo/tree/main/inlang/source-code/paraglide).
|
|
189
203
|
|
|
190
204
|
<doc-links>
|
|
205
|
+
<doc-link title="NextJS + Paraglide JS" icon="lucide:codesandbox" href="https://stackblitz.com/~/LorisSigrist/paraglide-next-app-router-example" description="Play around with NextJS and Paraglide JS"></doc-link>
|
|
191
206
|
<doc-link title="Svelte + Paraglide JS" icon="lucide:codesandbox" href="https://stackblitz.com/~/github.com/LorisSigrist/paraglide-sveltekit-example" description="Play around with Svelte and Paraglide JS"></doc-link>
|
|
192
207
|
<doc-link title="Astro + Paraglide JS" icon="lucide:codesandbox" href="https://stackblitz.com/~/github.com/LorisSigrist/paraglide-astro-example" description="Play around with Astro and Paraglide JS"></doc-link>
|
|
193
208
|
</doc-links>
|
|
@@ -207,7 +222,7 @@ Inlang Paraglide-JS consists of four main parts:
|
|
|
207
222
|
| **Compiler** | Compiles messages into tree-shakable message functions |
|
|
208
223
|
| **Messages** | The compiled tree-shakable message functions |
|
|
209
224
|
| **Runtime** | A runtime that resolves the [language tag](https://www.inlang.com/m/8y8sxj09/library-inlang-languageTag) of the current user |
|
|
210
|
-
| **Adapter** | (optional) An adapter that adjusts the runtime for different frameworks
|
|
225
|
+
| **Adapter** | (optional) An adapter that adjusts the runtime for different frameworks |
|
|
211
226
|
|
|
212
227
|
## Compiler
|
|
213
228
|
|
|
@@ -283,14 +298,12 @@ console.log(hello({ name: "Samuel" }))
|
|
|
283
298
|
|
|
284
299
|
# Writing an Adapter
|
|
285
300
|
|
|
286
|
-
|
|
301
|
+
An "adapter" is a library that integrates with a framework's liefcycle and does two main things:
|
|
287
302
|
|
|
288
|
-
|
|
303
|
+
- Calls `setLanguageTag()` at appropriate times to set the language
|
|
304
|
+
- Reacts to `onSetLanguageTag()`, usually by navigating or relading the page.
|
|
289
305
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
1. `setLanguageTag()` can be used to set a getter function for the [language tag](https://www.inlang.com/m/8y8sxj09/library-inlang-languageTag). The getter function can be used to resolve server-side language tags or to resolve the language tag from a global state management library like Redux or Vuex.
|
|
293
|
-
2. `onSetLanguageTag()` can be used to trigger side-effects such as updating the UI, or requesting the site in the new language from the server.
|
|
306
|
+
Here is an example that adapts Paraglide-JS to a fictitious metaframework like NextJS or SvelteKit.
|
|
294
307
|
|
|
295
308
|
```tsx
|
|
296
309
|
import { setLanguageTag, onSetLanguageTag } from "../paraglide/runtime.js"
|
|
@@ -324,7 +337,7 @@ else {
|
|
|
324
337
|
})
|
|
325
338
|
}
|
|
326
339
|
|
|
327
|
-
//
|
|
340
|
+
// make sure the app renders _after_ you've done your setup
|
|
328
341
|
render((page) => (
|
|
329
342
|
<html lang={request.languageTag}>
|
|
330
343
|
<body>{page}</body>
|
|
@@ -334,8 +347,9 @@ render((page) => (
|
|
|
334
347
|
|
|
335
348
|
# Community
|
|
336
349
|
|
|
337
|
-
We are grateful for all the support we get from the community. Here are
|
|
338
|
-
|
|
350
|
+
We are grateful for all the support we get from the community. Here are a few comments we've received recently.
|
|
351
|
+
|
|
352
|
+
If you have any feedback / problems, please let us know on [GitHub](https://github.com/opral/inlang-paraglide-js/issues/new)
|
|
339
353
|
|
|
340
354
|
<doc-comments>
|
|
341
355
|
<doc-comment text="Just tried Paraglide JS from @inlangHQ. This is how i18n should be done! Totally new level of DX for both implementation and managing translations! Superb support for SvelteKit as well ⭐" author="Patrik Engborg" icon="mdi:twitter" data-source="https://twitter.com/patrikengborg/status/1747260930873053674"></doc-comment>
|
|
@@ -347,7 +361,7 @@ Of course we are open to and value criticism as well. If you have any feedback,
|
|
|
347
361
|
|
|
348
362
|
# Roadmap
|
|
349
363
|
|
|
350
|
-
Of course, we're not done yet! We plan on adding the following features to Paraglide JS
|
|
364
|
+
Of course, we're not done yet! We plan on adding the following features to Paraglide JS soon:
|
|
351
365
|
|
|
352
366
|
- [ ] Pluralization ([Join the Discussion](https://github.com/opral/monorepo/discussions/2025))
|
|
353
367
|
- [ ] Formatting of numbers and dates ([Join the Discussion](https://github.com/opral/monorepo/discussions/992))
|
|
@@ -367,6 +381,6 @@ Paraglide JS is part of the inlang ecosystem, so it integrates nicely with all t
|
|
|
367
381
|
- [Fink](https://inlang.com/m/tdozzpar/app-inlang-finkLocalizationEditor) - An Online UI for editing translations. Changes made in Fink are committed to a translation branch or submitted via pull request.
|
|
368
382
|
- [Parrot](https://inlang.com/m/gkrpgoir/app-parrot-figmaPlugin) - A Figma Plugin for previewing translations right in your Figma designs. This avoids any layout issues that might occur due to different text lengths in different languages.
|
|
369
383
|
|
|
370
|
-
# Pricing
|
|
384
|
+
# Pricing
|
|
371
385
|
|
|
372
386
|
<doc-pricing></doc-pricing>
|
package/dist/index.js
CHANGED
|
@@ -35660,8 +35660,11 @@ function reexportAliases(message) {
|
|
|
35660
35660
|
* @see inlang.com/link.
|
|
35661
35661
|
* ---
|
|
35662
35662
|
* @deprecated reference the message by id \`m.${message.id}()\` instead
|
|
35663
|
+
*
|
|
35664
|
+
* @param {Parameters<typeof ${message.id}>} args
|
|
35665
|
+
* @returns {ReturnType<typeof ${message.id}>}
|
|
35663
35666
|
*/
|
|
35664
|
-
export const ${message.alias["default"]} = ${message.id};
|
|
35667
|
+
export const ${message.alias["default"]} = (...args) => ${message.id}(...args);
|
|
35665
35668
|
`;
|
|
35666
35669
|
}
|
|
35667
35670
|
return code;
|
|
@@ -40054,8 +40057,9 @@ async function pathExists2(filePath, nodeishFs) {
|
|
|
40054
40057
|
}
|
|
40055
40058
|
|
|
40056
40059
|
// ../../cross-sell/cross-sell-sherlock/dist/recommendation/recommendation.js
|
|
40060
|
+
var vsCodePath = "./.vscode";
|
|
40057
40061
|
async function addRecommendationToWorkspace(fs3, workingDirectory) {
|
|
40058
|
-
const vscodeFolderPath = normalizePath(joinPath(workingDirectory ?? "",
|
|
40062
|
+
const vscodeFolderPath = workingDirectory ? normalizePath(joinPath(workingDirectory ?? "", vsCodePath)) : vsCodePath;
|
|
40059
40063
|
const extensionsJsonPath = joinPath(vscodeFolderPath, "extensions.json");
|
|
40060
40064
|
if (!await pathExists2(vscodeFolderPath, fs3)) {
|
|
40061
40065
|
await fs3.mkdir(vscodeFolderPath);
|
|
@@ -40081,7 +40085,7 @@ async function addRecommendationToWorkspace(fs3, workingDirectory) {
|
|
|
40081
40085
|
}
|
|
40082
40086
|
}
|
|
40083
40087
|
async function isInWorkspaceRecommendation(fs3, workingDirectory) {
|
|
40084
|
-
const vscodeFolderPath = normalizePath(joinPath(workingDirectory ?? "",
|
|
40088
|
+
const vscodeFolderPath = workingDirectory ? normalizePath(joinPath(workingDirectory ?? "", vsCodePath)) : vsCodePath;
|
|
40085
40089
|
const extensionsJsonPath = joinPath(vscodeFolderPath, "extensions.json");
|
|
40086
40090
|
if (!await pathExists2(extensionsJsonPath, fs3) || !await pathExists2(vscodeFolderPath, fs3)) {
|
|
40087
40091
|
return false;
|
|
@@ -40094,11 +40098,11 @@ async function isInWorkspaceRecommendation(fs3, workingDirectory) {
|
|
|
40094
40098
|
}
|
|
40095
40099
|
|
|
40096
40100
|
// ../../cross-sell/cross-sell-sherlock/dist/index.js
|
|
40097
|
-
async function isAdopted(
|
|
40098
|
-
return isInWorkspaceRecommendation(
|
|
40101
|
+
async function isAdopted(args) {
|
|
40102
|
+
return isInWorkspaceRecommendation(args.fs, args.workingDirectory);
|
|
40099
40103
|
}
|
|
40100
|
-
async function add2(
|
|
40101
|
-
await addRecommendationToWorkspace(
|
|
40104
|
+
async function add2(args) {
|
|
40105
|
+
await addRecommendationToWorkspace(args.fs, args.workingDirectory);
|
|
40102
40106
|
}
|
|
40103
40107
|
|
|
40104
40108
|
// src/cli/commands/init.ts
|
|
@@ -40199,8 +40203,8 @@ var maybeAddVsCodeExtension = async (args, ctx) => {
|
|
|
40199
40203
|
project.setSettings(settings);
|
|
40200
40204
|
}
|
|
40201
40205
|
try {
|
|
40202
|
-
if (!await isAdopted(ctx.repo.nodeishFs)) {
|
|
40203
|
-
await add2(ctx.repo.nodeishFs);
|
|
40206
|
+
if (!await isAdopted({ fs: ctx.repo.nodeishFs })) {
|
|
40207
|
+
await add2({ fs: ctx.repo.nodeishFs });
|
|
40204
40208
|
ctx.logger.success(
|
|
40205
40209
|
"Added the inlang Visual Studio Code extension (Sherlock) to the workspace recommendations."
|
|
40206
40210
|
);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inlang/paraglide-js",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.3",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -64,12 +64,12 @@
|
|
|
64
64
|
"typescript": "5.2.2",
|
|
65
65
|
"vitest": "0.34.3",
|
|
66
66
|
"@inlang/env-variables": "0.2.0",
|
|
67
|
-
"@inlang/cross-sell-sherlock": "0.0.
|
|
67
|
+
"@inlang/cross-sell-sherlock": "0.0.3",
|
|
68
68
|
"@inlang/language-tag": "1.5.1",
|
|
69
69
|
"@inlang/telemetry": "0.3.14",
|
|
70
|
+
"@inlang/sdk": "0.27.0",
|
|
70
71
|
"@lix-js/client": "0.9.0",
|
|
71
72
|
"@lix-js/fs": "0.6.0",
|
|
72
|
-
"@inlang/sdk": "0.27.0",
|
|
73
73
|
"@inlang/plugin-message-format": "2.1.1"
|
|
74
74
|
},
|
|
75
75
|
"exports": {
|