@inlang/paraglide-js 1.0.0-prerelease.13 → 1.0.0-prerelease.15
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 +53 -51
- package/dist/cli/commands/init.d.ts +11 -10
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3398 -49559
- package/dist/services/file-handling/write-output.d.ts +0 -1
- package/dist/services/logger/index.d.ts +21 -0
- package/package.json +12 -10
package/README.md
CHANGED
|
@@ -22,7 +22,12 @@ npx @inlang/paraglide-js@latest init
|
|
|
22
22
|
<doc-feature title="Typesafety" image="https://cdn.jsdelivr.net/gh/inlang/monorepo@latest/inlang/source-code/paraglide/paraglide-js/assets/typesafe.png"></doc-feature>
|
|
23
23
|
</doc-features>
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
### Treeshaking
|
|
26
|
+
|
|
27
|
+
<doc-figure src="https://cdn.jsdelivr.net/gh/inlang/monorepo@latest/inlang/source-code/paraglide/paraglide-js/assets/tree-shaking.jpg" alt="An illustration explaining the benefits of treeshaking in software" caption="How Paraglide JS treeshaking works">
|
|
28
|
+
</doc-figure>
|
|
29
|
+
|
|
30
|
+
Treeshaking gives us superpowers. With it, each page of your app only loads the messages that it actually uses. Incremental loading like this would usually take hours of manual tweaking to get right. With Paraglide-JS you get it for free. Say goodbye to huge bundles.
|
|
26
31
|
|
|
27
32
|
|
|
28
33
|
# Getting started
|
|
@@ -30,6 +35,7 @@ npx @inlang/paraglide-js@latest init
|
|
|
30
35
|
### 1. Initialize paraglide-js
|
|
31
36
|
|
|
32
37
|
You can initialize paraglide-js by running the following command in your terminal:
|
|
38
|
+
|
|
33
39
|
```bash
|
|
34
40
|
npx @inlang/paraglide-js@latest init
|
|
35
41
|
```
|
|
@@ -41,7 +47,7 @@ Having an adapter is only required if you want to use paraglide-js with a framew
|
|
|
41
47
|
<doc-links>
|
|
42
48
|
<doc-link title="Adapter for Svelte" icon="simple-icons:svelte" href="https://github.com/inlang/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-svelte/example" description="Go to GitHub example"></doc-link>
|
|
43
49
|
<doc-link title="Adapter for SolidJS" icon="tabler:brand-solidjs" href="https://discord.com/channels/897438559458430986/1163823207128776795" description="View progress"></doc-link>
|
|
44
|
-
<doc-link title="Adapter for NextJS" icon="tabler:brand-nextjs" href="https://github.com/inlang/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-next
|
|
50
|
+
<doc-link title="Adapter for NextJS" icon="tabler:brand-nextjs" href="https://github.com/inlang/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-next" description="Go to GitHub example"></doc-link>
|
|
45
51
|
<doc-link title="Adapter for Vite" icon="tabler:brand-vite" href="https://github.com/inlang/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-vite" description="Go to GitHub"></doc-link>
|
|
46
52
|
</doc-links>
|
|
47
53
|
|
|
@@ -55,9 +61,9 @@ You can customize the `compile` script to your needs. For example, you can add a
|
|
|
55
61
|
|
|
56
62
|
```json
|
|
57
63
|
{
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
"scripts": {
|
|
65
|
+
"compile": "paraglide-js compile"
|
|
66
|
+
}
|
|
61
67
|
}
|
|
62
68
|
```
|
|
63
69
|
|
|
@@ -93,15 +99,16 @@ m.loginHeader({ name: "Samuel" }) // Hallo Samuel, bitte melde dich an, um fortz
|
|
|
93
99
|
|
|
94
100
|
Paraglide JS provides five exports in `./paraglide/runtime.js`:
|
|
95
101
|
|
|
96
|
-
| Variable
|
|
97
|
-
|
|
|
98
|
-
| `sourceLanguageTag`
|
|
99
|
-
| `availableLanguageTags` | All language tags of the current project
|
|
100
|
-
| `languageTag()`
|
|
101
|
-
| `setLanguageTag()`
|
|
102
|
-
| `onSetLanguageTag()`
|
|
102
|
+
| Variable | Description |
|
|
103
|
+
| ----------------------- | --------------------------------------------------------------------- |
|
|
104
|
+
| `sourceLanguageTag` | The source language tag of the project |
|
|
105
|
+
| `availableLanguageTags` | All language tags of the current project |
|
|
106
|
+
| `languageTag()` | Returns the language tag of the current user |
|
|
107
|
+
| `setLanguageTag()` | Sets the language tag of the current user |
|
|
108
|
+
| `onSetLanguageTag()` | Registers a listener that is called whenever the language tag changes |
|
|
103
109
|
|
|
104
110
|
## Setting the language
|
|
111
|
+
|
|
105
112
|
You can set the current language tag by calling `setLanguageTag()`. Any subsequent calls to either `languageTag()` or a message function will return the new language tag.
|
|
106
113
|
|
|
107
114
|
```js
|
|
@@ -118,6 +125,7 @@ m.hello() // Hello world!
|
|
|
118
125
|
The language tag is global, so you need to be careful with it on the server to make sure multiple requests don't interfere with each other. That's why we recommend using an adapter for your framework. Adapters integrate with the framework's lifecycle and ensure that the language tag is managed correctly.
|
|
119
126
|
|
|
120
127
|
## Reacting to a language change
|
|
128
|
+
|
|
121
129
|
You can react to a language change by calling `onSetLanguageTag()`. This function is called whenever the language tag changes.
|
|
122
130
|
|
|
123
131
|
```js
|
|
@@ -125,7 +133,7 @@ import { setLanguageTag, onSetLanguageTag } from "./paraglide/runtime"
|
|
|
125
133
|
import * as m from "./paraglide/messages"
|
|
126
134
|
|
|
127
135
|
onSetLanguageTag((newLanguageTag) => {
|
|
128
|
-
|
|
136
|
+
console.log(`The language changed to ${newLanguageTag}`)
|
|
129
137
|
})
|
|
130
138
|
|
|
131
139
|
setLanguageTag("de") // The language changed to de
|
|
@@ -133,12 +141,14 @@ setLanguageTag("en") // The language changed to en
|
|
|
133
141
|
```
|
|
134
142
|
|
|
135
143
|
There are a few things to know about `onSetLanguageTag()`:
|
|
144
|
+
|
|
136
145
|
- You can only register one listener. If you register a second listener it will throw an error.
|
|
137
146
|
- It shouldn't be used on the server.
|
|
138
147
|
|
|
139
148
|
The main use case for `onSetLanguageTag()` is to trigger a rerender of your app's UI when the language changes. Again, if you are using an adapter this is handled for you.
|
|
140
149
|
|
|
141
150
|
## Forcing a language
|
|
151
|
+
|
|
142
152
|
It's common that you need to force a message to be in a certain language, especially on the server. You can do this by passing an options object to the message function as a
|
|
143
153
|
second parameter.
|
|
144
154
|
|
|
@@ -176,12 +186,12 @@ The emitted functions are often referred to as "message functions". By emitting
|
|
|
176
186
|
|
|
177
187
|
Inlang Paraglide-JS consists of four main parts:
|
|
178
188
|
|
|
179
|
-
| Part
|
|
180
|
-
|
|
|
181
|
-
| **Compiler** | Compiles messages into tree-shakable message functions
|
|
182
|
-
| **Messages** | The compiled tree-shakable message functions
|
|
183
|
-
| **Runtime**
|
|
184
|
-
| **Adapter**
|
|
189
|
+
| Part | Description |
|
|
190
|
+
| ------------ | -------------------------------------------------------------------------- |
|
|
191
|
+
| **Compiler** | Compiles messages into tree-shakable message functions |
|
|
192
|
+
| **Messages** | The compiled tree-shakable message functions |
|
|
193
|
+
| **Runtime** | A runtime that resolves the language tag of the current user |
|
|
194
|
+
| **Adapter** | (if required) An adapter that adjusts the runtime for different frameworks |
|
|
185
195
|
|
|
186
196
|
## Compiler
|
|
187
197
|
|
|
@@ -190,6 +200,7 @@ The compiler loads an inlang project and compiles the messages into tree-shakabl
|
|
|
190
200
|
#### Example
|
|
191
201
|
|
|
192
202
|
**Input**
|
|
203
|
+
|
|
193
204
|
```js
|
|
194
205
|
// messages/en.json
|
|
195
206
|
{
|
|
@@ -199,6 +210,7 @@ The compiler loads an inlang project and compiles the messages into tree-shakabl
|
|
|
199
210
|
```
|
|
200
211
|
|
|
201
212
|
**Output**
|
|
213
|
+
|
|
202
214
|
```js
|
|
203
215
|
// src/paraglide/messages.js
|
|
204
216
|
|
|
@@ -207,11 +219,11 @@ The compiler loads an inlang project and compiles the messages into tree-shakabl
|
|
|
207
219
|
* @param {string} params.name
|
|
208
220
|
*/
|
|
209
221
|
function hello({ name }) {
|
|
210
|
-
|
|
222
|
+
return `Hello ${name}!`
|
|
211
223
|
}
|
|
212
224
|
|
|
213
225
|
function loginButton() {
|
|
214
|
-
|
|
226
|
+
return "Login"
|
|
215
227
|
}
|
|
216
228
|
```
|
|
217
229
|
|
|
@@ -228,21 +240,19 @@ Three compiled message functions exist in an example project.
|
|
|
228
240
|
```js
|
|
229
241
|
// src/paraglide/messages.js
|
|
230
242
|
|
|
231
|
-
|
|
232
243
|
export function hello(params) {
|
|
233
|
-
|
|
244
|
+
return `Hello ${params.name}!`
|
|
234
245
|
}
|
|
235
246
|
|
|
236
247
|
export function loginButton() {
|
|
237
|
-
|
|
248
|
+
return "Login"
|
|
238
249
|
}
|
|
239
250
|
|
|
240
251
|
export function loginHeader(params) {
|
|
241
|
-
|
|
252
|
+
return `Hello ${params.name}, please login to continue.`
|
|
242
253
|
}
|
|
243
254
|
```
|
|
244
255
|
|
|
245
|
-
|
|
246
256
|
Only the message `hello` is used in the source code.
|
|
247
257
|
|
|
248
258
|
```js
|
|
@@ -259,13 +269,12 @@ The bundler tree shakes (removes) `loginButton` and `loginHeader` and only inclu
|
|
|
259
269
|
// output/index.js
|
|
260
270
|
|
|
261
271
|
function hello(params) {
|
|
262
|
-
|
|
272
|
+
return `Hello ${params.name}!`
|
|
263
273
|
}
|
|
264
274
|
|
|
265
|
-
console.log(hello({ name: "Samuel"}))
|
|
275
|
+
console.log(hello({ name: "Samuel" }))
|
|
266
276
|
```
|
|
267
277
|
|
|
268
|
-
|
|
269
278
|
## Runtime
|
|
270
279
|
|
|
271
280
|
View the source of `./paraglide/runtime.js` to find the latest runtime API and documentation.
|
|
@@ -277,7 +286,6 @@ Paraglide-JS can be adapted to any framework or environment by calling `setLangu
|
|
|
277
286
|
1. `setLanguageTag()` can be used to set a getter function for the language tag. 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.
|
|
278
287
|
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.
|
|
279
288
|
|
|
280
|
-
|
|
281
289
|
# Writing an Adapter
|
|
282
290
|
|
|
283
291
|
The following example adapts Paraglide-JS to a fictitious metaframework like NextJS, SolidStart, SvelteKit, or Nuxt.
|
|
@@ -287,14 +295,10 @@ The goal is to provide a high-level understanding of how to adapt Paraglide-JS t
|
|
|
287
295
|
1. `setLanguageTag()`: to set the language tag
|
|
288
296
|
2. `onSetLanguageTag()`: to trigger a side-effect when the language changes
|
|
289
297
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
298
|
```tsx
|
|
294
299
|
import { setLanguageTag, onSetLanguageTag } from "./paraglide/runtime"
|
|
295
300
|
import { isServer, request, render } from "@example/framework"
|
|
296
301
|
|
|
297
|
-
|
|
298
302
|
// On a server, the language tag needs to be resolved on a
|
|
299
303
|
// per-request basis. Hence, we need to pass a getter
|
|
300
304
|
// function () => string to setLanguageTag.
|
|
@@ -302,8 +306,8 @@ import { isServer, request, render } from "@example/framework"
|
|
|
302
306
|
// Most frameworks offer a way to access the current
|
|
303
307
|
// request. In this example, we assume that the language tag
|
|
304
308
|
// is available in the request object.
|
|
305
|
-
if (isServer){
|
|
306
|
-
|
|
309
|
+
if (isServer) {
|
|
310
|
+
setLanguageTag(() => request.languageTag)
|
|
307
311
|
}
|
|
308
312
|
// On a client, the language tag could be resolved from
|
|
309
313
|
// the document's html lang tag.
|
|
@@ -311,26 +315,24 @@ if (isServer){
|
|
|
311
315
|
// In addition, we also want to trigger a side-effect
|
|
312
316
|
// to request the site if the language changes.
|
|
313
317
|
else {
|
|
314
|
-
|
|
318
|
+
setLanguageTag(() => document.documentElement.lang)
|
|
315
319
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
320
|
+
//! Make sure to call `onSetLanguageTag` after
|
|
321
|
+
//! the initial language tag has been set to
|
|
322
|
+
//! avoid an infinite loop.
|
|
319
323
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
+
// route to the page in the new language
|
|
325
|
+
onSetLanguageTag((newLanguageTag) => {
|
|
326
|
+
window.location.pathname = `/${newLanguageTag}${window.location.pathname}`
|
|
327
|
+
})
|
|
324
328
|
}
|
|
325
329
|
|
|
326
330
|
// render the app
|
|
327
|
-
render((page) =>
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
</html>
|
|
333
|
-
)
|
|
331
|
+
render((page) => (
|
|
332
|
+
<html lang={request.languageTag}>
|
|
333
|
+
<body>{page}</body>
|
|
334
|
+
</html>
|
|
335
|
+
))
|
|
334
336
|
```
|
|
335
337
|
|
|
336
338
|
# Community
|
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { type ProjectSettings } from "@inlang/sdk";
|
|
3
|
+
import { Logger } from "../../services/logger/index.js";
|
|
3
4
|
export declare const initCommand: Command;
|
|
4
|
-
export declare const initializeInlangProject: () => Promise<string>;
|
|
5
|
+
export declare const initializeInlangProject: (logger: Logger) => Promise<string>;
|
|
5
6
|
export declare const maybeAddVsCodeExtension: (args: {
|
|
6
7
|
projectPath: string;
|
|
7
|
-
}) => Promise<void>;
|
|
8
|
-
export declare const addParaglideJsToDevDependencies: () => Promise<void>;
|
|
8
|
+
}, logger: Logger) => Promise<void>;
|
|
9
|
+
export declare const addParaglideJsToDevDependencies: (logger: Logger) => Promise<void>;
|
|
9
10
|
export declare const findExistingInlangProjectPath: () => Promise<string | undefined>;
|
|
10
11
|
export declare const existingProjectFlow: (args: {
|
|
11
12
|
existingProjectPath: string;
|
|
12
|
-
}) => Promise<undefined>;
|
|
13
|
-
export declare const createNewProjectFlow: () => Promise<undefined>;
|
|
13
|
+
}, logger: Logger) => Promise<undefined>;
|
|
14
|
+
export declare const createNewProjectFlow: (logger: Logger) => Promise<undefined>;
|
|
14
15
|
export declare const newProjectTemplate: ProjectSettings;
|
|
15
|
-
export declare const checkIfPackageJsonExists: () => Promise<undefined>;
|
|
16
|
-
export declare const checkIfUncommittedChanges: () => Promise<void>;
|
|
16
|
+
export declare const checkIfPackageJsonExists: (logger: Logger) => Promise<undefined>;
|
|
17
|
+
export declare const checkIfUncommittedChanges: (logger: Logger) => Promise<void>;
|
|
17
18
|
export declare const addCompileStepToPackageJSON: (args: {
|
|
18
19
|
projectPath: string;
|
|
19
|
-
}) => Promise<undefined>;
|
|
20
|
+
}, logger: Logger) => Promise<undefined>;
|
|
20
21
|
/**
|
|
21
22
|
* Ensures that the moduleResolution compiler option is set to "bundler" or similar in the tsconfig.json.
|
|
22
23
|
*
|
|
23
24
|
* Otherwise, types defined in `package.exports` are not resolved by TypeScript. Leading to type
|
|
24
25
|
* errors with Paraglide-JS.
|
|
25
26
|
*/
|
|
26
|
-
export declare const maybeChangeTsConfigModuleResolution: () => Promise<void>;
|
|
27
|
+
export declare const maybeChangeTsConfigModuleResolution: (logger: Logger) => Promise<void>;
|
|
27
28
|
/**
|
|
28
29
|
* Paraligde JS compiles to JS with JSDoc comments. TypeScript doesn't allow JS files by default.
|
|
29
30
|
*/
|
|
30
|
-
export declare const maybeChangeTsConfigAllowJs: () => Promise<void>;
|
|
31
|
+
export declare const maybeChangeTsConfigAllowJs: (logger: Logger) => Promise<void>;
|
package/dist/index.d.ts
CHANGED