Skip to content

Commit 7ef1c36

Browse files
Add docs for SvelteKit MF2 integration (#59)
Co-authored-by: Luca Casonato <[email protected]>
1 parent e03f9bd commit 7ef1c36

File tree

5 files changed

+233
-1
lines changed

5 files changed

+233
-1
lines changed

docs/_data.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ sidebar:
1919
- docs/integration/c/
2020
- docs/integration/cpp/
2121
- docs/frameworks/angular/
22+
- docs/frameworks/sveltekit/
2223
- docs/lsp/

docs/frameworks/sveltekit.md

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
---
2+
title: Using MF2 with SvelteKit
3+
sidebar_title: SvelteKit
4+
---
5+
6+
This guide explains how to localize SvelteKit applications using the
7+
`sveltekit-mf2` library.
8+
9+
This library takes care of locale selection, MF2 parsing, and rendering. Because
10+
it is based on [`@sveltekit-i18n/base`](https://github.com/sveltekit-i18n/base)
11+
it supports shipping the minimum amount of translations to the client for each
12+
route.
13+
14+
## Installation and setup
15+
16+
In an existing SvelteKit project, install the SvelteKit integration package
17+
together with the MF2 engine, and `@sveltekit-i18n/base`.
18+
19+
```bash
20+
npm install sveltekit-mf2 @sveltekit-i18n/base
21+
```
22+
23+
You can also use a different package manager like `yarn`, `pnpm`, or `deno` to
24+
install the packages.
25+
26+
## Defining translations and locale manifest
27+
28+
In your application's `lib` folder, create a folder for every locale you want to
29+
support (e.g., `en`, `es`, `fr`). Inside each locale folder, create JSON files
30+
for different translation namespaces (e.g., `common.json`, `home.json`). You
31+
will later load one or more of these files for every route in your application.
32+
33+
You should split your translations into namespaces based on the routes where
34+
they are used. For example, if you have a homepage and an about page, you might
35+
create `home.json` and `about.json` files, and a `common.json` file for shared
36+
translations.
37+
38+
```
39+
lib/
40+
en/
41+
common.json
42+
home.json
43+
about.json
44+
es/
45+
common.json
46+
home.json
47+
about.json
48+
```
49+
50+
```json
51+
// en/common.json
52+
{
53+
"greeting": "Hello, {#bold}{$name}!{/bold}",
54+
"farewell": "Goodbye!"
55+
}
56+
```
57+
58+
```json
59+
// es/common.json
60+
{
61+
"greeting": "¡Hola, {#bold}{$name}!{/bold}",
62+
"farewell": "¡Adiós!"
63+
}
64+
```
65+
66+
> In the JSON files, every translation string can use MF2 syntax for formatting
67+
> and interpolation. See the [Quick Start](/docs/quick-start/#basic-syntax) for
68+
> more details on the syntax.
69+
70+
Then create a `translations.ts` file in your `lib` folder to configure the i18n
71+
setup. This file will define the translations available for each locale and
72+
namespace, and set up the parser for MF2.
73+
74+
```ts
75+
import i18n from "@sveltekit-i18n/base";
76+
77+
const config = {
78+
loaders: [
79+
{
80+
locale: "en",
81+
key: "common",
82+
loader: async () => (await import("./en/common.json")).default,
83+
},
84+
{
85+
locale: "es",
86+
key: "common",
87+
loader: async () => (await import("./es/common.json")).default,
88+
},
89+
{
90+
locale: "en",
91+
key: "home",
92+
routes: ["/"],
93+
loader: async () => (await import("./en/home.json")).default,
94+
},
95+
{
96+
locale: "es",
97+
key: "home",
98+
routes: ["/"],
99+
loader: async () => (await import("./es/home.json")).default,
100+
},
101+
{
102+
locale: "en",
103+
key: "about",
104+
routes: ["/about"],
105+
loader: async () => (await import("./en/about.json")).default,
106+
},
107+
{
108+
locale: "es",
109+
key: "about",
110+
routes: ["/about"],
111+
loader: async () => (await import("./es/about.json")).default,
112+
},
113+
],
114+
parser: {
115+
parse(value: string, [props]: Record<string, any>[], locale: string) {
116+
return { value, props, locale };
117+
},
118+
},
119+
};
120+
121+
export const { setLocale, t, locale, locales, loading, loadTranslations } =
122+
new i18n(config);
123+
```
124+
125+
Then configure your root layout (`routes/+layout.js`) to load the translations:
126+
127+
```ts
128+
import { loadTranslations } from "$lib/translations";
129+
130+
/** @type {import('@sveltejs/kit').Load} */
131+
export const load = async ({ url }) => {
132+
const { pathname } = url;
133+
134+
const initLocale = "en"; // hard code, or get from cookie, user session, ...
135+
136+
await loadTranslations(initLocale, pathname); // keep this just before the `return`
137+
138+
return {};
139+
};
140+
```
141+
142+
Finally, wrap your application in the `FormatterProvider` component in
143+
`routes/+layout.svelte`:
144+
145+
```svelte
146+
<script lang="ts">
147+
import { FormatterProvider } from "sveltekit-mf2";
148+
import { t } from "$lib/translations";
149+
150+
let { children } = $props();
151+
</script>
152+
153+
<FormatterProvider {t}>
154+
<!-- You can put other layout content here, wrapping the {@render children()} -->
155+
{@render children()}
156+
</FormatterProvider>
157+
```
158+
159+
## Using the Formatter component
160+
161+
You can now use the `<Formatter>` component anywhere in your SvelteKit
162+
application to render localized and formatted strings.
163+
164+
```svelte
165+
<script lang="ts">
166+
import { Formatter } from "sveltekit-mf2";
167+
</script>
168+
169+
<Formatter id="common.greeting" values={{ name: "SvelteKit" }} />
170+
<Formatter id="common.farewell" />
171+
```
172+
173+
You can use the `values` prop to pass variables to the MF2 strings. The `id`
174+
prop should be in the format `namespace.key`, where `namespace` is the key
175+
defined in the loader configuration, and `key` is the key in the JSON file.
176+
177+
The `values` prop is optional if your MF2 string does not require any variables.
178+
179+
## Switching locales
180+
181+
You can switch locales by calling the `setLocale` function from your
182+
`translations.ts` file. For example, you can create buttons to switch between
183+
English and Spanish:
184+
185+
```svelte
186+
<script lang="ts">
187+
import { setLocale } from "$lib/translations";
188+
189+
function switchToEnglish() {
190+
setLocale("en");
191+
}
192+
193+
function switchToSpanish() {
194+
setLocale("es");
195+
}
196+
</script>
197+
198+
<div>
199+
<button onclick={switchToEnglish}>English</button>
200+
<button onclick={switchToSpanish}>Spanish</button>
201+
</div>
202+
```
203+
204+
## Further reading
205+
206+
- [@sveltekit-i18n/base documentation](https://github.com/sveltekit-i18n/base)
207+
208+
## Reference docs
209+
210+
This package exports two main components: a provider to set up the i18n context,
211+
and a formatter component to render localized strings.
212+
213+
### `<FormatterProvider>`
214+
215+
Props:
216+
217+
- `t` - The `t` function from the `i18n` object
218+
219+
### `<Formatter>`
220+
221+
Props:
222+
223+
- `id: string` - Translation key (e.g., "common.greeting")
224+
- `values?: Record<string, any>` - Variables to interpolate into the message

docs/integration/js.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ advanced uses are possible, which are documented in the API documentation.
1313
> number of higher-level framework-specific integration packages are available:
1414
>
1515
> - [Angular](../../frameworks/angular)
16+
> - [SvelteKit](../../frameworks/sveltekit)
1617
1718
## Installation and setup
1819

docs/quick-start.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ To use MessageFormat 2 in a project, follow these set up guides:
1515
- [C](/docs/integration/c)
1616
- [C++](/docs/integration/cpp)
1717

18+
If you are using a web framework, you may want to check out one of the
19+
framework-specific integration guides and packages:
20+
21+
- [Angular](/docs/frameworks/angular)
22+
- [SvelteKit](/docs/frameworks/sveltekit)
23+
1824
To set up your editor or IDE to work with MessageFormat 2, see the
1925
[editor setup](/docs/lsp) guide.
2026

static/css/style.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@
159159
}
160160

161161
.markdown pre {
162-
@apply bg-gray-100 p-4 rounded font-mono text-base overflow-y-auto;
162+
@apply bg-gray-100 p-4 rounded font-mono text-base overflow-y-auto my-4;
163163
font-variant-ligatures: none;
164164
}
165165

0 commit comments

Comments
 (0)