@inlang/paraglide-js 1.0.0-prerelease.9 → 1.0.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/README.md +230 -95
- package/bin/run.js +2 -3
- package/dist/cli/commands/compile.d.ts +0 -1
- package/dist/cli/commands/compile.test.d.ts +0 -1
- package/dist/cli/commands/init.d.ts +11 -11
- package/dist/cli/commands/init.test.d.ts +0 -1
- package/dist/cli/main.d.ts +0 -1
- package/dist/cli/state.d.ts +0 -1
- package/dist/compiler/compile.d.ts +0 -1
- package/dist/compiler/compile.test.d.ts +0 -1
- package/dist/compiler/compileMessage.d.ts +10 -6
- package/dist/compiler/compileMessage.test.d.ts +0 -1
- package/dist/compiler/compilePattern.d.ts +0 -1
- package/dist/compiler/compilePattern.test.d.ts +0 -1
- package/dist/compiler/optionsType.d.ts +3 -0
- package/dist/compiler/optionsType.test.d.ts +1 -0
- package/dist/compiler/paramsType.d.ts +1 -2
- package/dist/compiler/paramsType.test.d.ts +0 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +13442 -0
- package/dist/services/codegen/escape.d.ts +9 -0
- package/dist/services/codegen/identifier.d.ts +7 -0
- package/dist/services/codegen/indentifier.test.d.ts +1 -0
- package/dist/services/codegen/quotes.d.ts +3 -0
- package/dist/services/codegen/string-union.d.ts +1 -0
- package/dist/services/file-handling/write-output.d.ts +3 -0
- package/dist/services/file-handling/write-output.test.d.ts +1 -0
- package/dist/services/logger/index.d.ts +21 -0
- package/dist/services/telemetry/events.d.ts +6 -0
- package/dist/services/telemetry/implementation.d.ts +23 -0
- package/dist/services/telemetry/index.d.ts +1 -0
- package/dist/services/valid-js-identifier/index.d.ts +5 -0
- package/dist/services/valid-js-identifier/index.test.d.ts +1 -0
- package/dist/services/valid-js-identifier/reservedWords.d.ts +1 -0
- package/dist/utils/git.d.ts +15 -0
- package/package.json +73 -42
- package/dist/cli/commands/compile.d.ts.map +0 -1
- package/dist/cli/commands/compile.js +0 -51
- package/dist/cli/commands/compile.test.d.ts.map +0 -1
- package/dist/cli/commands/compile.test.js +0 -103
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/init.js +0 -338
- package/dist/cli/commands/init.test.d.ts.map +0 -1
- package/dist/cli/commands/init.test.js +0 -618
- package/dist/cli/main.d.ts.map +0 -1
- package/dist/cli/main.js +0 -10
- package/dist/cli/state.d.ts.map +0 -1
- package/dist/cli/state.js +0 -25
- package/dist/compiler/compile.d.ts.map +0 -1
- package/dist/compiler/compile.js +0 -182
- package/dist/compiler/compile.test.d.ts.map +0 -1
- package/dist/compiler/compile.test.js +0 -385
- package/dist/compiler/compileMessage.d.ts.map +0 -1
- package/dist/compiler/compileMessage.js +0 -82
- package/dist/compiler/compileMessage.test.d.ts.map +0 -1
- package/dist/compiler/compileMessage.test.js +0 -108
- package/dist/compiler/compilePattern.d.ts.map +0 -1
- package/dist/compiler/compilePattern.js +0 -28
- package/dist/compiler/compilePattern.test.d.ts.map +0 -1
- package/dist/compiler/compilePattern.test.js +0 -26
- package/dist/compiler/paramsType.d.ts.map +0 -1
- package/dist/compiler/paramsType.js +0 -17
- package/dist/compiler/paramsType.test.d.ts.map +0 -1
- package/dist/compiler/paramsType.test.js +0 -6
package/README.md
CHANGED
|
@@ -1,39 +1,90 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
<!--  -->
|
|
2
|
+
|
|
3
|
+
[<img src="https://cdn.loom.com/sessions/thumbnails/a8365ec4fa2c4f6bbbf4370cf22dd7f6-with-play.gif" width="100%" /> Watch the pre-release demo of Paraglide JS](https://www.youtube.com/watch?v=-YES3CCAG90)
|
|
4
|
+
|
|
5
|
+
Attention: The following features are missing and will be added in the upcoming weeks:
|
|
6
|
+
|
|
7
|
+
- [ ] Support for pluralization
|
|
8
|
+
|
|
9
|
+
# The i18n library that you can set up within 3 lines of code
|
|
10
|
+
|
|
11
|
+
Type in the following command into your terminal to get started immediately:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @inlang/paraglide-js@latest init
|
|
15
|
+
```
|
|
5
16
|
|
|
6
|
-
|
|
17
|
+
# Features
|
|
18
|
+
|
|
19
|
+
<doc-features>
|
|
20
|
+
<doc-feature title="No unused translations" image="https://cdn.jsdelivr.net/gh/inlang/monorepo@latest/inlang/source-code/paraglide/paraglide-js/assets/unused-translations.png"></doc-feature>
|
|
21
|
+
<doc-feature title="Reduced payload" image="https://cdn.jsdelivr.net/gh/inlang/monorepo@latest/inlang/source-code/paraglide/paraglide-js/assets/reduced-payload.png"></doc-feature>
|
|
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
|
+
</doc-features>
|
|
24
|
+
|
|
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.
|
|
7
31
|
|
|
8
|
-
- [x] the smallest, fastest, and most typesafe i18n library
|
|
9
|
-
- [x] only bundles the messages that are used (tree-shaking)
|
|
10
|
-
- [x] storage agnostic (JSON, YAML, CSV, etc.)
|
|
11
|
-
- [x] plug & play with the [inlang ecosystem](https://inlang.com/marketplace)
|
|
12
32
|
|
|
13
33
|
# Getting started
|
|
14
34
|
|
|
15
|
-
1.
|
|
35
|
+
### 1. Initialize paraglide-js
|
|
36
|
+
|
|
37
|
+
You can initialize paraglide-js by running the following command in your terminal:
|
|
16
38
|
|
|
17
39
|
```bash
|
|
18
40
|
npx @inlang/paraglide-js@latest init
|
|
19
41
|
```
|
|
20
42
|
|
|
21
|
-
2. (
|
|
43
|
+
### 2. Select an adapter (if required)
|
|
44
|
+
|
|
45
|
+
Having an adapter is only required if you want to use paraglide-js with a framework. If you don't use a framework, you can skip this step.
|
|
46
|
+
|
|
47
|
+
<doc-links>
|
|
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>
|
|
49
|
+
<doc-link title="Adapter for SolidJS" icon="tabler:brand-solidjs" href="https://inlang.com/m/n860p17j/library-inlang-paraglideJsAdapterSolidStart" description="Go to Adapter"></doc-link>
|
|
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>
|
|
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>
|
|
52
|
+
</doc-links>
|
|
53
|
+
|
|
54
|
+
#### Alternatively, [you can write your own adapter](#writing-an-adapter)
|
|
55
|
+
|
|
56
|
+
### 3. Add the `compile` script to your `package.json`
|
|
22
57
|
|
|
23
|
-
|
|
58
|
+
> If you are using `@inlang/paraglide-js-adapter-vite`, you can skip this step.
|
|
24
59
|
|
|
25
|
-
|
|
60
|
+
You can customize the `compile` script to your needs. For example, you can add a `--watch` flag to watch for changes, if you have installed a watcher.
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"scripts": {
|
|
65
|
+
"compile": "paraglide-js compile --project ./project.inlang",
|
|
66
|
+
"watch": "paraglide-js compile --project ./project.inlang --watch"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
26
70
|
|
|
27
71
|
# Usage
|
|
28
72
|
|
|
29
|
-
|
|
73
|
+
Running the `compile` script will generate a `src/paraglide` folder. This folder contains all the code that you need to use paraglide-js.
|
|
74
|
+
Throughout this guide, you will see imports from `./paraglide/*`. These are all to this folder.
|
|
75
|
+
|
|
76
|
+
> Tip: If you are using a bundler, you can set up an alias to `./src/paraglide` to make the imports shorter. We recommend `$paraglide/*`
|
|
77
|
+
|
|
78
|
+
## Using Messages
|
|
79
|
+
|
|
80
|
+
The compiled messages are placed in `./paraglide/messages.js`. You can import them all with `import * as m from "./paraglide/messages"`. Don't worry, your bundler will only bundle the messages that you actually use.
|
|
30
81
|
|
|
31
82
|
```js
|
|
32
83
|
// m is a namespace that contains all messages of your project
|
|
33
84
|
// a bundler like rollup or webpack only bundles
|
|
34
85
|
// the messages that are used
|
|
35
|
-
import * as m from "./paraglide
|
|
36
|
-
import { setLanguageTag } from "./paraglide
|
|
86
|
+
import * as m from "./paraglide/messages"
|
|
87
|
+
import { setLanguageTag } from "./paraglide/runtime"
|
|
37
88
|
|
|
38
89
|
// use a message
|
|
39
90
|
m.hello() // Hello world!
|
|
@@ -45,103 +96,186 @@ m.loginHeader({ name: "Samuel" }) // Hello Samuel, please login to continue.
|
|
|
45
96
|
setLanguageTag("de")
|
|
46
97
|
|
|
47
98
|
m.loginHeader({ name: "Samuel" }) // Hallo Samuel, bitte melde dich an, um fortzufahren.
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
If you want to dynamically choose between a set of messages, you can create a record of messages and index into it. Note that this will not be tree-shaken by your bundler.
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
import * as m from "./paraglide/messages"
|
|
105
|
+
|
|
106
|
+
const season = {
|
|
107
|
+
spring: m.spring,
|
|
108
|
+
summer: m.summer,
|
|
109
|
+
autumn: m.autumn,
|
|
110
|
+
winter: m.winter,
|
|
111
|
+
}
|
|
48
112
|
|
|
113
|
+
const msg = season["spring"]() // Hello spring!
|
|
49
114
|
```
|
|
50
115
|
|
|
51
|
-
Paraglide JS
|
|
116
|
+
Paraglide JS provides five exports in `./paraglide/runtime.js`:
|
|
52
117
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
118
|
+
| Variable | Description |
|
|
119
|
+
| -------------------------- | --------------------------------------------------------------------- |
|
|
120
|
+
| `sourceLanguageTag` | The source language tag of the project |
|
|
121
|
+
| `availableLanguageTags` | All language tags of the current project |
|
|
122
|
+
| `languageTag()` | Returns the language tag of the current user |
|
|
123
|
+
| `setLanguageTag()` | Sets the language tag of the current user |
|
|
124
|
+
| `onSetLanguageTag()` | Registers a listener that is called whenever the language tag changes |
|
|
125
|
+
| `isAvailableLanguageTag()` | Checks if a value is a valid language tag |
|
|
57
126
|
|
|
127
|
+
## Setting the language
|
|
58
128
|
|
|
129
|
+
You can set the current [language tag](/m/8y8sxj09/library-inlang-languageTag) by calling `setLanguageTag()`. Any subsequent calls to either `languageTag()` or a message function will return the new language tag.
|
|
59
130
|
|
|
60
|
-
|
|
131
|
+
```js
|
|
132
|
+
import { setLanguageTag } from "./paraglide/runtime"
|
|
133
|
+
import * as m from "./paraglide/messages"
|
|
61
134
|
|
|
62
|
-
|
|
135
|
+
setLanguageTag("de")
|
|
136
|
+
m.hello() // Hallo Welt!
|
|
63
137
|
|
|
64
|
-
|
|
138
|
+
setLanguageTag("en")
|
|
139
|
+
m.hello() // Hello world!
|
|
140
|
+
```
|
|
65
141
|
|
|
66
|
-
|
|
142
|
+
The [language tag](/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. 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.
|
|
67
143
|
|
|
68
|
-
|
|
69
|
-
- `MESSAGES`: the compiled tree-shakable message functions
|
|
70
|
-
- `RUNTIME`: a runtime that resolves the language tag of the current user
|
|
71
|
-
- `ADAPTER`: (if required) an adapter that adjusts the runtime for different frameworks
|
|
144
|
+
## Reacting to a language change
|
|
72
145
|
|
|
73
|
-
|
|
146
|
+
You can react to a language change by calling `onSetLanguageTag()`. This function is called whenever the [language tag](/m/8y8sxj09/library-inlang-languageTag) changes.
|
|
74
147
|
|
|
148
|
+
```js
|
|
149
|
+
import { setLanguageTag, onSetLanguageTag } from "./paraglide/runtime"
|
|
150
|
+
import * as m from "./paraglide/messages"
|
|
75
151
|
|
|
76
|
-
|
|
152
|
+
onSetLanguageTag((newLanguageTag) => {
|
|
153
|
+
console.log(`The language changed to ${newLanguageTag}`)
|
|
154
|
+
})
|
|
77
155
|
|
|
78
|
-
|
|
156
|
+
setLanguageTag("de") // The language changed to de
|
|
157
|
+
setLanguageTag("en") // The language changed to en
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
There are a few things to know about `onSetLanguageTag()`:
|
|
161
|
+
|
|
162
|
+
- You can only register one listener. If you register a second listener it will throw an error.
|
|
163
|
+
- It shouldn't be used on the server.
|
|
79
164
|
|
|
80
|
-
|
|
165
|
+
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.
|
|
81
166
|
|
|
82
|
-
|
|
167
|
+
## Forcing a language
|
|
168
|
+
|
|
169
|
+
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
|
|
170
|
+
second parameter.
|
|
83
171
|
|
|
84
172
|
```js
|
|
85
|
-
|
|
173
|
+
import * as m from "./paraglide/messages"
|
|
174
|
+
const msg = m.hello({ name: "Samuel" }, { languageTag: "de" }) // Hallo Samuel!
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Usage with a Bundler
|
|
178
|
+
|
|
179
|
+
We provide a few bundler plugins to make it easier to use paraglide-js with a bundler. If you
|
|
180
|
+
are using one of these bundlers, we recommed using the corresponding plugin.
|
|
181
|
+
|
|
182
|
+
- [Rollup](https://github.com/inlang/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-rollup)
|
|
183
|
+
- [Webpack](https://github.com/inlang/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-webpack)
|
|
184
|
+
- [Vite](https://github.com/inlang/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-vite)
|
|
185
|
+
|
|
186
|
+
These plugins make sure to rerun the `compile` script whenever you build your project. That way you don't need to modify your build script in `package.json`. If you are using a bundler with a dev-server, like Vite, the plugins also make sure to rerun the `compile` script whenever your messages change.
|
|
187
|
+
|
|
188
|
+
# Playground
|
|
189
|
+
|
|
190
|
+
You can find many examples for how to use paraglide on codesandbox:
|
|
191
|
+
|
|
192
|
+
<doc-links>
|
|
193
|
+
<doc-link title="Svelte + Paraglide JS" icon="lucide:codesandbox" href="https://dub.sh/paraglide-playground-svelte" description="Play around with Svelte and Paraglide JS"></doc-link>
|
|
194
|
+
</doc-links>
|
|
195
|
+
|
|
196
|
+
# Architecture
|
|
197
|
+
|
|
198
|
+
Inlang Paraglide JS leverages a compiler to emit vanilla JavaScript functions.
|
|
199
|
+
|
|
200
|
+
The emitted functions are often referred to as "message functions". By emitting message functions, inlang Paraglide JS eliminates a class of edge cases while also being simpler, faster, and more reliable than other i18n libraries. The compiled runtime contains less than 50 LOC (lines of code) and is less than 1kb gzipped.
|
|
201
|
+
|
|
202
|
+

|
|
203
|
+
|
|
204
|
+
Inlang Paraglide-JS consists of four main parts:
|
|
205
|
+
|
|
206
|
+
| Part | Description |
|
|
207
|
+
| ------------ | -------------------------------------------------------------------------- |
|
|
208
|
+
| **Compiler** | Compiles messages into tree-shakable message functions |
|
|
209
|
+
| **Messages** | The compiled tree-shakable message functions |
|
|
210
|
+
| **Runtime** | A runtime that resolves the [language tag](/m/8y8sxj09/library-inlang-languageTag) of the current user |
|
|
211
|
+
| **Adapter** | (if required) An adapter that adjusts the runtime for different frameworks |
|
|
212
|
+
|
|
213
|
+
## Compiler
|
|
214
|
+
|
|
215
|
+
The compiler loads an inlang project and compiles the messages into tree-shakable and typesafe message functions.
|
|
86
216
|
|
|
87
|
-
|
|
217
|
+
#### Example
|
|
88
218
|
|
|
89
|
-
|
|
219
|
+
**Input**
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
// messages/en.json
|
|
223
|
+
{
|
|
224
|
+
"hello": "Hello {name}!",
|
|
225
|
+
"loginButton": "Login"
|
|
226
|
+
}
|
|
90
227
|
```
|
|
91
228
|
|
|
92
|
-
|
|
229
|
+
**Output**
|
|
93
230
|
|
|
94
231
|
```js
|
|
95
|
-
//
|
|
232
|
+
// src/paraglide/messages.js
|
|
96
233
|
|
|
97
234
|
/**
|
|
98
235
|
* @param {object} params
|
|
99
236
|
* @param {string} params.name
|
|
100
237
|
*/
|
|
101
238
|
function hello({ name }) {
|
|
102
|
-
|
|
239
|
+
return `Hello ${name}!`
|
|
103
240
|
}
|
|
104
241
|
|
|
105
242
|
function loginButton() {
|
|
106
|
-
|
|
243
|
+
return "Login"
|
|
107
244
|
}
|
|
108
245
|
```
|
|
109
246
|
|
|
247
|
+
## Messages
|
|
110
248
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
The compiled messages are importable as a namespace import (`import * as m`).
|
|
249
|
+
The compiled messages are importable as a namespace import (`import * as m`).
|
|
114
250
|
|
|
115
251
|
The namespace import ensures that bundlers like Rollup, Webpack, or Turbopack can tree-shake the messages that are not used.
|
|
116
252
|
|
|
117
|
-
|
|
253
|
+
#### Example
|
|
118
254
|
|
|
119
255
|
Three compiled message functions exist in an example project.
|
|
120
256
|
|
|
121
257
|
```js
|
|
122
|
-
//
|
|
123
|
-
|
|
258
|
+
// src/paraglide/messages.js
|
|
124
259
|
|
|
125
260
|
export function hello(params) {
|
|
126
|
-
|
|
261
|
+
return `Hello ${params.name}!`
|
|
127
262
|
}
|
|
128
263
|
|
|
129
264
|
export function loginButton() {
|
|
130
|
-
|
|
265
|
+
return "Login"
|
|
131
266
|
}
|
|
132
267
|
|
|
133
268
|
export function loginHeader(params) {
|
|
134
|
-
|
|
269
|
+
return `Hello ${params.name}, please login to continue.`
|
|
135
270
|
}
|
|
136
271
|
```
|
|
137
272
|
|
|
138
|
-
|
|
139
273
|
Only the message `hello` is used in the source code.
|
|
140
274
|
|
|
141
275
|
```js
|
|
142
276
|
// source/index.js
|
|
143
277
|
|
|
144
|
-
import * as m from "./
|
|
278
|
+
import * as m from "./paraglide/messages"
|
|
145
279
|
|
|
146
280
|
console.log(m.hello({ name: "Samuel" }))
|
|
147
281
|
```
|
|
@@ -152,79 +286,80 @@ The bundler tree shakes (removes) `loginButton` and `loginHeader` and only inclu
|
|
|
152
286
|
// output/index.js
|
|
153
287
|
|
|
154
288
|
function hello(params) {
|
|
155
|
-
|
|
289
|
+
return `Hello ${params.name}!`
|
|
156
290
|
}
|
|
157
291
|
|
|
158
|
-
console.log(hello({ name: "Samuel"}))
|
|
292
|
+
console.log(hello({ name: "Samuel" }))
|
|
159
293
|
```
|
|
160
294
|
|
|
295
|
+
## Runtime
|
|
161
296
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
View the source of your imports from `./paraglide-js/` to find the latest runtime API and documentation.
|
|
165
|
-
|
|
166
|
-
## ADAPTER
|
|
297
|
+
View the source of `./paraglide/runtime.js` to find the latest runtime API and documentation.
|
|
167
298
|
|
|
299
|
+
## Adapter
|
|
168
300
|
|
|
301
|
+
Paraglide-JS can be adapted to any framework or environment by calling `setLanguageTag()` and `onSetLanguageTag()`.
|
|
169
302
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
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.
|
|
303
|
+
1. `setLanguageTag()` can be used to set a getter function for the [language tag](/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.
|
|
173
304
|
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.
|
|
174
305
|
|
|
306
|
+
# Writing an Adapter
|
|
175
307
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
The following example adapts Paraglide-JS to a fictitious metaframework like NextJS, SolidStart, SvelteKit, or Nuxt.
|
|
308
|
+
The following example adapts Paraglide-JS to a fictitious metaframework like NextJS, SolidStart, SvelteKit, or Nuxt.
|
|
179
309
|
|
|
180
310
|
The goal is to provide a high-level understanding of how to adapt Paraglide-JS to a framework. Besides this example, we recommend viewing the source-code of available adapters. In general, only two functions need to be called to adapt Paraglide-JS to a framework:
|
|
181
311
|
|
|
182
|
-
1. `setLanguageTag()`: to set the language tag
|
|
312
|
+
1. `setLanguageTag()`: to set the [language tag](/m/8y8sxj09/library-inlang-languageTag)
|
|
183
313
|
2. `onSetLanguageTag()`: to trigger a side-effect when the language changes
|
|
184
314
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
315
|
```tsx
|
|
189
|
-
import { setLanguageTag, onSetLanguageTag } from "./paraglide
|
|
316
|
+
import { setLanguageTag, onSetLanguageTag } from "./paraglide/runtime"
|
|
190
317
|
import { isServer, request, render } from "@example/framework"
|
|
191
318
|
|
|
192
|
-
|
|
193
|
-
//
|
|
194
|
-
// per-request basis. Hence, we need to pass a getter
|
|
319
|
+
// On a server, the language tag needs to be resolved on a
|
|
320
|
+
// per-request basis. Hence, we need to pass a getter
|
|
195
321
|
// function () => string to setLanguageTag.
|
|
196
|
-
//
|
|
322
|
+
//
|
|
197
323
|
// Most frameworks offer a way to access the current
|
|
198
324
|
// request. In this example, we assume that the language tag
|
|
199
325
|
// is available in the request object.
|
|
200
|
-
if (isServer){
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
// On a client, the language tag could be resolved from
|
|
326
|
+
if (isServer) {
|
|
327
|
+
setLanguageTag(() => request.languageTag)
|
|
328
|
+
}
|
|
329
|
+
// On a client, the language tag could be resolved from
|
|
204
330
|
// the document's html lang tag.
|
|
205
331
|
//
|
|
206
332
|
// In addition, we also want to trigger a side-effect
|
|
207
333
|
// to request the site if the language changes.
|
|
208
334
|
else {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
335
|
+
setLanguageTag(() => document.documentElement.lang)
|
|
336
|
+
|
|
337
|
+
//! Make sure to call `onSetLanguageTag` after
|
|
338
|
+
//! the initial language tag has been set to
|
|
339
|
+
//! avoid an infinite loop.
|
|
340
|
+
|
|
341
|
+
// route to the page in the new language
|
|
342
|
+
onSetLanguageTag((newLanguageTag) => {
|
|
343
|
+
window.location.pathname = `/${newLanguageTag}${window.location.pathname}`
|
|
344
|
+
})
|
|
219
345
|
}
|
|
220
346
|
|
|
221
347
|
// render the app
|
|
222
|
-
render((page) =>
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
</html>
|
|
228
|
-
)
|
|
348
|
+
render((page) => (
|
|
349
|
+
<html lang={request.languageTag}>
|
|
350
|
+
<body>{page}</body>
|
|
351
|
+
</html>
|
|
352
|
+
))
|
|
229
353
|
```
|
|
230
354
|
|
|
355
|
+
# Community
|
|
356
|
+
|
|
357
|
+
We are grateful for all the support we get from the community. Here are just a few of the comments we've received over the last few weeks.
|
|
358
|
+
Of course we are open to and value criticism as well. If you have any feedback, please let us know directly on [GitHub](https://github.com/inlang/monorepo/discussions/1464)
|
|
359
|
+
|
|
360
|
+
<doc-comments>
|
|
361
|
+
<doc-comment text="The lib is great guys!" author="ktarmyshov" icon="mdi:github"></doc-comment>
|
|
362
|
+
<doc-comment text="Thank you for that huge work you have done and still doing!" author="ZerdoX-x" icon="mdi:github"></doc-comment>
|
|
363
|
+
<doc-comment text="[...] the switch between the sdk-js and paraglide has been pretty great! " author="albbus" icon="mdi:discord"></doc-comment>
|
|
364
|
+
<doc-comment text="Thanks for all the great work @Samuel Stroschein" author="Willem" icon="mdi:discord"></doc-comment>
|
|
365
|
+
</doc-comments>
|
package/bin/run.js
CHANGED
|
@@ -1,31 +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
|
|
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
|
-
//# sourceMappingURL=init.d.ts.map
|
|
31
|
+
export declare const maybeChangeTsConfigAllowJs: (logger: Logger) => Promise<void>;
|
package/dist/cli/main.d.ts
CHANGED
package/dist/cli/state.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import { type Message } from "@inlang/sdk";
|
|
1
|
+
import { LanguageTag, type Message } from "@inlang/sdk";
|
|
2
|
+
type Resource = {
|
|
3
|
+
index: string;
|
|
4
|
+
[languageTag: string]: string;
|
|
5
|
+
};
|
|
2
6
|
/**
|
|
3
7
|
* Returns the compiled messages for the given message.
|
|
4
8
|
*
|
|
@@ -8,9 +12,9 @@ import { type Message } from "@inlang/sdk";
|
|
|
8
12
|
* en: "export const hello_world = (params) => { ... }",
|
|
9
13
|
* de: "export const hello_world = (params) => { ... }",
|
|
10
14
|
* }
|
|
15
|
+
*
|
|
16
|
+
* @param message The message to compile
|
|
17
|
+
* @param lookupTable A table that maps language tags to their fallbacks.
|
|
11
18
|
*/
|
|
12
|
-
export declare const compileMessage: (message: Message) =>
|
|
13
|
-
|
|
14
|
-
index: string;
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=compileMessage.d.ts.map
|
|
19
|
+
export declare const compileMessage: (message: Message, availableLanguageTags: LanguageTag[], sourceLanguageTag: LanguageTag) => Resource;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -8,5 +8,4 @@ export type Params = Record<string, "NonNullable<unknown>">;
|
|
|
8
8
|
* const jsdoc = jsdocFromParams({ name: "NonNullable<unknown>", count: "NonNullable<unknown>" })
|
|
9
9
|
* const message = `/** ${paramsType} *\/ const mes2 => \`Hello ${params.name}! You have ${params.count} messages.\``
|
|
10
10
|
*/
|
|
11
|
-
export declare const paramsType: (params: Params) => string;
|
|
12
|
-
//# sourceMappingURL=paramsType.d.ts.map
|
|
11
|
+
export declare const paramsType: (params: Params, isMessagesIndex: boolean) => string;
|
package/dist/index.d.ts
ADDED