@inlang/paraglide-js 1.3.2 → 1.3.4
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 +126 -149
- package/dist/index.js +21071 -4865
- package/package.json +9 -11
package/README.md
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<!--  -->
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Get started instantly with the following command:
|
|
5
|
+
Get started with:
|
|
8
6
|
|
|
9
7
|
```bash
|
|
10
8
|
npx @inlang/paraglide-js@latest init
|
|
@@ -13,9 +11,9 @@ npx @inlang/paraglide-js@latest init
|
|
|
13
11
|
# Features
|
|
14
12
|
|
|
15
13
|
<doc-features>
|
|
16
|
-
<doc-feature title="
|
|
17
|
-
<doc-feature title="
|
|
18
|
-
<doc-feature title="
|
|
14
|
+
<doc-feature title="Only used translations are shipped" image="https://cdn.jsdelivr.net/gh/opral/monorepo@latest/inlang/source-code/paraglide/paraglide-js/assets/unused-translations.png"></doc-feature>
|
|
15
|
+
<doc-feature title="Tiny Bundle-Size" image="https://cdn.jsdelivr.net/gh/opral/monorepo@latest/inlang/source-code/paraglide/paraglide-js/assets/reduced-payload.png"></doc-feature>
|
|
16
|
+
<doc-feature title="Typesafe" image="https://cdn.jsdelivr.net/gh/opral/monorepo@latest/inlang/source-code/paraglide/paraglide-js/assets/typesafe.png"></doc-feature>
|
|
19
17
|
</doc-features>
|
|
20
18
|
|
|
21
19
|
### Treeshaking
|
|
@@ -29,7 +27,7 @@ Treeshaking gives us superpowers. With it, each page of your app only loads the
|
|
|
29
27
|
|
|
30
28
|
### 1. Initialize paraglide-js
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
Initialize ParaglideJS whith:
|
|
33
31
|
|
|
34
32
|
```bash
|
|
35
33
|
npx @inlang/paraglide-js@latest init
|
|
@@ -37,19 +35,19 @@ npx @inlang/paraglide-js@latest init
|
|
|
37
35
|
|
|
38
36
|
This will:
|
|
39
37
|
|
|
40
|
-
1. Install
|
|
41
|
-
2.
|
|
42
|
-
3. Set up
|
|
38
|
+
1. Install necessary dependencies
|
|
39
|
+
2. Add the Paraglide compiler to your `build` script
|
|
40
|
+
3. Set up configuration files
|
|
43
41
|
|
|
44
42
|
### 2. Set up an adapter (optional)
|
|
45
43
|
|
|
46
|
-
Adapters are framework
|
|
44
|
+
Adapters are framework-integrations for Paraglide. If you are using a framework, using an adapter is recommended , but not required.
|
|
47
45
|
|
|
48
46
|
<doc-links>
|
|
49
|
-
<doc-link title="Adapter for NextJS" icon="tabler:brand-nextjs" href="
|
|
50
|
-
<doc-link title="Adapter for SvelteKit" icon="simple-icons:svelte" href="
|
|
51
|
-
<doc-link title="Adapter for
|
|
52
|
-
<doc-link title="Adapter for
|
|
47
|
+
<doc-link title="Adapter for NextJS" icon="tabler:brand-nextjs" href="/m/osslbuzt/library-inlang-paraglideJsAdapterNextJs" description="Go to Library"></doc-link>
|
|
48
|
+
<doc-link title="Adapter for SvelteKit" icon="simple-icons:svelte" href="/m/dxnzrydw/library-inlang-paraglideJsAdapterSvelteKit" description="Go to Library"></doc-link>
|
|
49
|
+
<doc-link title="Adapter for Astro" icon="devicon-plain:astro" href="/m/iljlwzfs/library-inlang-paraglideJsAdapterAstro" description="Go to Library"></doc-link>
|
|
50
|
+
<doc-link title="Adapter for SolidJS" icon="tabler:brand-solidjs" href="/m/n860p17j/library-inlang-paraglideJsAdapterSolidStart" description="Go to Library"></doc-link>
|
|
53
51
|
</doc-links>
|
|
54
52
|
|
|
55
53
|
#### Alternatively, [you can write your own adapter](#writing-an-adapter)
|
|
@@ -57,36 +55,33 @@ Adapters are framework specific integrations for Paraglide. If you are using a f
|
|
|
57
55
|
# Usage
|
|
58
56
|
|
|
59
57
|
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
58
|
|
|
62
|
-
|
|
59
|
+
## Adding Messages
|
|
60
|
+
|
|
61
|
+
By default, paraglide expects your messages to be in `messages/{lang}.json`.
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"hello": "Hello world!"
|
|
66
|
+
"loginHeader": "Hello {name}, please login to continue."
|
|
67
|
+
}
|
|
68
|
+
```
|
|
63
69
|
|
|
64
70
|
## Using Messages
|
|
65
71
|
|
|
66
|
-
|
|
72
|
+
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
73
|
|
|
68
74
|
```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
75
|
import * as m from "./paraglide/messages.js"
|
|
73
76
|
import { setLanguageTag } from "./paraglide/runtime.js"
|
|
74
77
|
|
|
75
|
-
// use a message
|
|
76
78
|
m.hello() // Hello world!
|
|
77
|
-
|
|
78
|
-
// message with parameters
|
|
79
79
|
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
80
|
```
|
|
86
81
|
|
|
87
|
-
If you want to
|
|
82
|
+
If you want to choose between messages at runtime, you can create a record of messages and index into it.
|
|
88
83
|
|
|
89
|
-
```
|
|
84
|
+
```ts
|
|
90
85
|
import * as m from "./paraglide/messages.js"
|
|
91
86
|
|
|
92
87
|
const season = {
|
|
@@ -94,26 +89,32 @@ const season = {
|
|
|
94
89
|
summer: m.summer,
|
|
95
90
|
autumn: m.autumn,
|
|
96
91
|
winter: m.winter,
|
|
97
|
-
}
|
|
92
|
+
} as const
|
|
98
93
|
|
|
99
94
|
const msg = season["spring"]() // Hello spring!
|
|
100
95
|
```
|
|
101
96
|
|
|
102
|
-
|
|
97
|
+
### Using the [Sherlock IDE Extension](https://inlang.com/m/r7kp499g/app-inlang-ideExtension) (optional)
|
|
98
|
+
|
|
99
|
+
[Sherlock](https://inlang.com/m/r7kp499g/app-inlang-ideExtension) integrates with paraglide to give you the optimal dev-experience.
|
|
100
|
+
|
|
101
|
+

|
|
102
|
+
|
|
103
|
+
## Adding Languages
|
|
104
|
+
|
|
105
|
+
You can declare which languages you support in `./project.inlang/settings.json`.
|
|
106
|
+
```json
|
|
107
|
+
// project.inlang/settings.json
|
|
108
|
+
{
|
|
109
|
+
"languageTags": ["en", "de"]
|
|
110
|
+
}
|
|
111
|
+
```
|
|
103
112
|
|
|
104
|
-
|
|
105
|
-
| --------------------------- | --------------------------------------------------------------------- |
|
|
106
|
-
| `sourceLanguageTag` | The source language tag of the project |
|
|
107
|
-
| `availableLanguageTags` | All language tags of the current project |
|
|
108
|
-
| `type AvailableLanguageTag` | An Type representing a valid language tag |
|
|
109
|
-
| `languageTag()` | Returns the language tag of the current user |
|
|
110
|
-
| `setLanguageTag()` | Sets the language tag of the current user |
|
|
111
|
-
| `onSetLanguageTag()` | Registers a listener that is called whenever the language tag changes |
|
|
112
|
-
| `isAvailableLanguageTag()` | Checks if a value is a valid language tag |
|
|
113
|
+
Then create another `messages/{lang}.json` file and get translating!
|
|
113
114
|
|
|
114
115
|
## Setting the language
|
|
115
116
|
|
|
116
|
-
You can set the
|
|
117
|
+
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
118
|
|
|
118
119
|
```js
|
|
119
120
|
import { setLanguageTag } from "./paraglide/runtime.js"
|
|
@@ -126,22 +127,15 @@ setLanguageTag("en")
|
|
|
126
127
|
m.hello() // Hello world!
|
|
127
128
|
```
|
|
128
129
|
|
|
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
|
+
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
|
|
|
131
|
-
|
|
132
|
+
You will need to call `setLanguageTag` on both the server and the client, since they run in separate processes.
|
|
132
133
|
|
|
133
|
-
|
|
134
|
+
## Reacting to language changes
|
|
134
135
|
|
|
135
|
-
|
|
136
|
-
// project.inlang/settings.json
|
|
137
|
-
{
|
|
138
|
-
"languageTags": ["en", "de"]
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Reacting to a language change
|
|
136
|
+
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
137
|
|
|
144
|
-
|
|
138
|
+
If you are using an adapter this is likely done for you.
|
|
145
139
|
|
|
146
140
|
```js
|
|
147
141
|
import { setLanguageTag, onSetLanguageTag } from "./paraglide/runtime.js"
|
|
@@ -158,70 +152,87 @@ setLanguageTag("en") // The language changed to en
|
|
|
158
152
|
There are a few things to know about `onSetLanguageTag()`:
|
|
159
153
|
|
|
160
154
|
- You can only register one listener. If you register a second listener it will throw an error.
|
|
161
|
-
-
|
|
155
|
+
- `setLanguageTag` shouldn't be used on the server.
|
|
162
156
|
|
|
163
|
-
|
|
157
|
+
## Getting a message in a specific language
|
|
164
158
|
|
|
165
|
-
|
|
159
|
+
You can import a message in a specific language from `paraglide/messages/{lang}.js`.
|
|
166
160
|
|
|
167
|
-
|
|
168
|
-
|
|
161
|
+
```ts
|
|
162
|
+
import * as m from "./paraglide/messages/de.js"
|
|
163
|
+
m.hello() // Hallo Welt
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
If you want to force a language, but don't know _which_ language ahead of time you can pass the `languageTag` option as the second parameter to a message function. This is often handy on the server.
|
|
169
167
|
|
|
170
168
|
```js
|
|
171
169
|
import * as m from "./paraglide/messages.js"
|
|
172
170
|
const msg = m.hello({ name: "Samuel" }, { languageTag: "de" }) // Hallo Samuel!
|
|
173
171
|
```
|
|
174
172
|
|
|
175
|
-
##
|
|
173
|
+
## Lazy-Loading
|
|
174
|
+
|
|
175
|
+
Paraglide consciously discourages lazy-loading translations since it seriously hurts
|
|
176
|
+
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).
|
|
176
177
|
|
|
177
|
-
|
|
178
|
-
are using one of these bundlers, we recommed using the corresponding plugin.
|
|
178
|
+
If you _really_ want to do it anway, you can lazily import the language-specific message files. Be careful with this.
|
|
179
179
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
180
|
+
```ts
|
|
181
|
+
const lazyGerman = await import("./paraglide/messages/de.js")
|
|
182
|
+
lazyGerman.hello() // Hallo Welt
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Usage with a Bundler
|
|
183
186
|
|
|
184
|
-
|
|
187
|
+
If you are using a bundler you should use the corresponding plugin. The plugin will keep your message-functions up-to-date by compiling whenever your messages change and before build.
|
|
188
|
+
|
|
189
|
+
<doc-links>
|
|
190
|
+
<doc-link title="Vite Plugin" icon="tabler:brand-vite" href="https://github.com/opral/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-vite" description="Go to Github"></doc-link>
|
|
191
|
+
<doc-link title="Rollup Plugin" icon="file-icons:rollup" href="https://github.com/opral/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-rollup" description="Go to Github"></doc-link>
|
|
192
|
+
<doc-link title="Webpack Plugin" icon="mdi:webpack" href="https://github.com/opral/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-webpack" description="Go to Github"></doc-link>
|
|
193
|
+
</doc-links>
|
|
185
194
|
|
|
186
195
|
# Playground
|
|
187
196
|
|
|
188
|
-
|
|
197
|
+
Find 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
198
|
|
|
190
199
|
<doc-links>
|
|
200
|
+
<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
201
|
<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
202
|
<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
203
|
</doc-links>
|
|
194
204
|
|
|
195
205
|
# Architecture
|
|
196
206
|
|
|
197
|
-
|
|
207
|
+
ParaglideJS leverages a compiler to generate vanilla JavaScript functions from your messages. We call these "message functions".
|
|
208
|
+
|
|
209
|
+
Message Functions are fully typed using JSDoc. They are exported individually from the `messages.js` file making them tree-shakable. They aren't reactive, they just return a string.
|
|
198
210
|
|
|
199
|
-
|
|
211
|
+
This avoids many edge cases associated with reactivity, lazy-loading and namespacing that other i18n libraries have to work around.
|
|
212
|
+
|
|
213
|
+
In addition to the message functions, ParaglideJS also emits a runtime. The runtime is used to set the language tag. It contains less than 50 LOC (lines of code) and is less than 300 bytes minified & gzipped.
|
|
200
214
|
|
|
201
215
|

|
|
202
216
|
|
|
203
|
-
|
|
217
|
+
Paraglide consists of four main parts:
|
|
204
218
|
|
|
205
219
|
| Part | Description |
|
|
206
220
|
| ------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
207
221
|
| **Compiler** | Compiles messages into tree-shakable message functions |
|
|
208
222
|
| **Messages** | The compiled tree-shakable message functions |
|
|
209
223
|
| **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
|
|
224
|
+
| **Adapter** | (optional) An adapter that adjusts the runtime for different frameworks |
|
|
211
225
|
|
|
212
226
|
## Compiler
|
|
213
227
|
|
|
214
|
-
The compiler loads an
|
|
215
|
-
|
|
216
|
-
#### Example
|
|
228
|
+
The compiler loads an Inlang project and compiles the messages into tree-shakable and typesafe message functions.
|
|
217
229
|
|
|
218
230
|
**Input**
|
|
219
231
|
|
|
220
232
|
```js
|
|
221
233
|
// messages/en.json
|
|
222
234
|
{
|
|
223
|
-
"hello": "Hello {name}!"
|
|
224
|
-
"loginButton": "Login"
|
|
235
|
+
"hello": "Hello {name}!"
|
|
225
236
|
}
|
|
226
237
|
```
|
|
227
238
|
|
|
@@ -235,96 +246,57 @@ The compiler loads an inlang project and compiles the messages into tree-shakabl
|
|
|
235
246
|
* @param {string} params.name
|
|
236
247
|
*/
|
|
237
248
|
export const hello = (params) => `Hello ${params.name}!`
|
|
238
|
-
|
|
239
|
-
/** ... */
|
|
240
|
-
export const loginButton = () => "Login"
|
|
241
249
|
```
|
|
242
250
|
|
|
243
251
|
## Messages
|
|
244
252
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
The namespace import ensures that bundlers like Rollup, Webpack, or Turbopack can tree-shake the messages that are not used.
|
|
248
|
-
|
|
249
|
-
#### Example
|
|
250
|
-
|
|
251
|
-
Three compiled message functions exist in an example project.
|
|
252
|
-
|
|
253
|
-
```js
|
|
254
|
-
// src/paraglide/messages.js
|
|
255
|
-
|
|
256
|
-
/** ... */
|
|
257
|
-
export const hello = (params) => `Hello ${params.name}!`
|
|
258
|
-
|
|
259
|
-
/** ... */
|
|
260
|
-
export const loginButton = () => "Login"
|
|
261
|
-
|
|
262
|
-
/** ... */
|
|
263
|
-
export const loginHeader = (params) => `Hello ${params.name}, please login to continue.`
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
Only the message `hello` is used in the source code.
|
|
253
|
+
By convention we import the compiled funcitions with a wildcard import.
|
|
267
254
|
|
|
268
255
|
```js
|
|
269
|
-
// src/my-code.js
|
|
270
256
|
import * as m from "../paraglide/messages.js"
|
|
271
|
-
|
|
272
|
-
console.log(m.hello({ name: "Samuel" }))
|
|
273
257
|
```
|
|
274
258
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
```js
|
|
278
|
-
// dist/my-code.js
|
|
279
|
-
const hello = (params) => `Hello ${params.name}!`
|
|
280
|
-
|
|
281
|
-
console.log(hello({ name: "Samuel" }))
|
|
282
|
-
```
|
|
259
|
+
Bundlers like Rollup, Webpack, or Turbopack tree-shake the messages that are not used, so using a wildcard import is perfectly fine.
|
|
283
260
|
|
|
284
261
|
# Writing an Adapter
|
|
285
262
|
|
|
286
|
-
|
|
263
|
+
An "Adapter" is a library that integrates with a framework's liefcycle and does two things:
|
|
287
264
|
|
|
288
|
-
|
|
265
|
+
1. Calls `setLanguageTag()` at appropriate times to set the language
|
|
266
|
+
2. Reacts to `onSetLanguageTag()`, usually by navigating or relading the page.
|
|
289
267
|
|
|
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.
|
|
268
|
+
This example adapts Paraglide to a fictitious fullstack framework.
|
|
294
269
|
|
|
295
270
|
```tsx
|
|
296
|
-
import { setLanguageTag, onSetLanguageTag } from "../paraglide/runtime.js"
|
|
297
|
-
import { isServer, request, render } from "@example/framework"
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
// per-request basis. Hence, we need to pass a getter
|
|
301
|
-
// function () => string to setLanguageTag.
|
|
302
|
-
//
|
|
303
|
-
// Most frameworks offer a way to access the current
|
|
304
|
-
// request. In this example, we assume that the language tag
|
|
305
|
-
// is available in the request object.
|
|
271
|
+
import { setLanguageTag, onSetLanguageTag, type AvailableLanguageTag } from "../paraglide/runtime.js"
|
|
272
|
+
import { isServer, isClient, request, render } from "@example/framework"
|
|
273
|
+
import { detectLanguage } from "./utils.js"
|
|
274
|
+
|
|
306
275
|
if (isServer) {
|
|
307
|
-
|
|
276
|
+
// On the server the language tag needs to be resolved on a per-request basis.
|
|
277
|
+
// Pass a getter function that resolves the language from the correct request
|
|
278
|
+
|
|
279
|
+
const detectLanguage = (request: Request) : AvailableLanguageTag => {
|
|
280
|
+
//your logic ...
|
|
281
|
+
}
|
|
282
|
+
setLanguageTag(() => detectLanguage(request))
|
|
308
283
|
}
|
|
309
|
-
// On a client, the language tag could be resolved from
|
|
310
|
-
// the document's html lang tag.
|
|
311
|
-
//
|
|
312
|
-
// In addition, we also want to trigger a side-effect
|
|
313
|
-
// to request the site if the language changes.
|
|
314
|
-
else {
|
|
315
|
-
setLanguageTag(() => document.documentElement.lang)
|
|
316
284
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
285
|
+
if(isClient) {
|
|
286
|
+
// On the client, the language tag can be resolved from
|
|
287
|
+
// the document's html lang tag.
|
|
288
|
+
setLanguageTag(() => document.documentElement.lang)
|
|
320
289
|
|
|
321
|
-
//
|
|
290
|
+
// When the language changes we want to re-render the page in the new language
|
|
291
|
+
// Here we just navigate to the new route
|
|
292
|
+
//
|
|
293
|
+
// Make sure to call `onSetLanguageTag` after `setLanguageTag` to avoid an infinite loop.
|
|
322
294
|
onSetLanguageTag((newLanguageTag) => {
|
|
323
295
|
window.location.pathname = `/${newLanguageTag}${window.location.pathname}`
|
|
324
296
|
})
|
|
325
297
|
}
|
|
326
298
|
|
|
327
|
-
//
|
|
299
|
+
// Render the app once the setup is done
|
|
328
300
|
render((page) => (
|
|
329
301
|
<html lang={request.languageTag}>
|
|
330
302
|
<body>{page}</body>
|
|
@@ -334,20 +306,21 @@ render((page) => (
|
|
|
334
306
|
|
|
335
307
|
# Community
|
|
336
308
|
|
|
337
|
-
We are grateful for all the support we get from the community. Here are
|
|
338
|
-
|
|
309
|
+
We are grateful for all the support we get from the community. Here are a few comments we've received recently.
|
|
310
|
+
|
|
311
|
+
If you have any feedback / problems, please let us know on [GitHub](https://github.com/opral/inlang-paraglide-js/issues/new)
|
|
339
312
|
|
|
340
313
|
<doc-comments>
|
|
341
314
|
<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>
|
|
315
|
+
<doc-comment text="I was messing with various i18n frameworks and tools in combination with Astro, and i must say that Paraglide was the smoothest experience. I have migrated my website from i18next and it was a breeze. SSG and SSR worked out of the box (which was the first one for me), and overall DX is great. Thanks for your work!" author="Dally H" icon="mdi:discord" data-source="https://discord.com/channels/897438559458430986/1096039983116202034/1220796380772307004"></doc-comment>
|
|
342
316
|
<doc-comment text="The lib is great guys!" author="ktarmyshov" icon="mdi:github"></doc-comment>
|
|
343
317
|
<doc-comment text="Thank you for that huge work you have done and still doing!" author="ZerdoX-x" icon="mdi:github"></doc-comment>
|
|
344
|
-
<doc-comment text="[...] the switch between the sdk-js and paraglide has been pretty great! " author="albbus" icon="mdi:discord"></doc-comment>
|
|
345
318
|
<doc-comment text="Thanks for all the great work @Samuel Stroschein" author="Willem" icon="mdi:discord"></doc-comment>
|
|
346
319
|
</doc-comments>
|
|
347
320
|
|
|
348
321
|
# Roadmap
|
|
349
322
|
|
|
350
|
-
Of course, we're not done yet! We plan on adding the following features to Paraglide JS
|
|
323
|
+
Of course, we're not done yet! We plan on adding the following features to Paraglide JS soon:
|
|
351
324
|
|
|
352
325
|
- [ ] Pluralization ([Join the Discussion](https://github.com/opral/monorepo/discussions/2025))
|
|
353
326
|
- [ ] Formatting of numbers and dates ([Join the Discussion](https://github.com/opral/monorepo/discussions/992))
|
|
@@ -360,13 +333,17 @@ Of course, we're not done yet! We plan on adding the following features to Parag
|
|
|
360
333
|
- Web Zurich December 2023
|
|
361
334
|
- [Svelte London January 2024](https://www.youtube.com/watch?v=eswNQiq4T2w&t=646s)
|
|
362
335
|
|
|
363
|
-
#
|
|
336
|
+
# Tooling
|
|
337
|
+
|
|
338
|
+
Paraglide JS is part of the Inlang ecosystem and integrates nicely with all the other Inlang compatible tools.
|
|
339
|
+
|
|
340
|
+
As a developer, you will love the [Sherlock IDE extension](http://localhost:4001/m/r7kp499g/app-inlang-ideExtension).
|
|
364
341
|
|
|
365
|
-
|
|
342
|
+
If you are working with translators or designers you will find these tools useful:
|
|
366
343
|
|
|
367
344
|
- [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
345
|
- [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
346
|
|
|
370
|
-
# Pricing
|
|
347
|
+
# Pricing
|
|
371
348
|
|
|
372
349
|
<doc-pricing></doc-pricing>
|