Skip to content

Commit 6ea9571

Browse files
committed
edits
1 parent b60f437 commit 6ea9571

File tree

1 file changed

+152
-86
lines changed

1 file changed

+152
-86
lines changed

docs/frameworks/sveltekit.md

Lines changed: 152 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -3,119 +3,188 @@ title: Using MF2 with SvelteKit
33
sidebar_title: SvelteKit
44
---
55

6-
A localization library for SvelteKit based on [sveltekit-i18n/base](https://github.com/sveltekit-i18n/base) and [MessageFormat2](https://messageformat.unicode.org/).
6+
This guide explains how to localize SvelteKit applications using the
7+
`sveltekit-mf2` library.
78

8-
### Installation
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.
913

10-
```bash
11-
npm install sveltekit-mf2
12-
```
13-
14-
## Guide
14+
## Installation and setup
1515

16-
### 1. Install @sveltekit-i18n/base and messageformat
16+
In an existing SvelteKit project, install the SvelteKit integration package
17+
together with the MF2 engine, and `@sveltekit-i18n/base`.
1718

1819
```bash
19-
npm install @sveltekit-i18n/base messageformat
20+
npm install sveltekit-mf2 @sveltekit-i18n/base messageformat
2021
```
2122

22-
### 2. Setup i18n
23+
You can also use a different package manager like `yarn`, `pnpm`, or `deno` to
24+
install the packages.
2325

24-
Create the `translations.ts` file in you `lib` folder.
25-
26-
```ts
27-
import i18n from "@sveltekit-i18n/base";
28-
const config = {
29-
// Add your languages in the loaderfunction either from JSON files or directly as JSON
30-
loaders: [
31-
{
32-
locale: "en",
33-
key: "common",
34-
loader: async () => (await import("./en/common.json")).default
35-
},
36-
{
37-
locale: "es",
38-
key: "common",
39-
loader: async () => (await import("./es/common.json")).default
40-
}
41-
],
42-
parser: {
43-
parse(value: string, [props]: Record<string, any>[], locale: string) {
44-
return { value, props, locale };
45-
}
46-
}
47-
};
26+
## Defining translations and locale manifest
4827

49-
export const { setLocale, t, locale, locales, loading, loadTranslations } = new i18n(config);
50-
```
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.
5132

52-
#### The locale files
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.
5337

54-
`en/common.json`
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+
```
5549

5650
```json
51+
// en/common.json
5752
{
58-
"test": "Hello {#bold}{$world}!{/bold}",
59-
"bye": "Bye"
53+
"greeting": "Hello, {#bold}{$name}!{/bold}",
54+
"farewell": "Goodbye!"
6055
}
6156
```
6257

63-
`es/common.json`
64-
6558
```json
59+
// es/common.json
6660
{
67-
"test": "Hola {#bold}{$world}!{/bold}",
68-
"bye": "adios"
61+
"greeting": "¡Hola, {#bold}{$name}!{/bold}",
62+
"farewell": "¡Adiós!"
6963
}
7064
```
7165

72-
##### Make sure to not change the parser!
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.
7369
74-
### 3. Use the FormatterProvider
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.
7573

76-
Inside of your `+layout.svelte` use the `<FormatterProvider>` by importing `t` and surrounding `{@render children}` with the provider.
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:
77126

78127
```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
79146
<script lang="ts">
80-
import favicon from '$lib/assets/favicon.svg';
81-
import { FormatterProvider } from 'sveltekit-mf2';
82-
import { t } from "$lib/translations"
147+
import { FormatterProvider } from "sveltekit-mf2";
148+
import { t } from "$lib/translations";
83149
84-
let { children } = $props();
150+
let { children } = $props();
85151
</script>
86152
87-
<svelte:head>
88-
<link rel="icon" href={favicon} />
89-
</svelte:head>
90-
91153
<FormatterProvider {t}>
92-
{@render children()}
154+
<!-- You can put other layout content here, wrapping the {@render children()} -->
155+
{@render children()}
93156
</FormatterProvider>
94157
```
95158

96-
### 4. Set the default locale and load the translations
97-
98-
Create a `layout.ts` file in your routes folder.
159+
## Using the Formatter component
99160

100-
```ts
101-
import { loadTranslations } from "$lib/translations";
161+
You can now use the `<Formatter>` component anywhere in your SvelteKit
162+
application to render localized and formatted strings.
102163

103-
const initLocale = "en";
164+
```svelte
165+
<script lang="ts">
166+
import { Formatter } from "sveltekit-mf2";
167+
</script>
104168
105-
export const load = async ({ url }) => {
106-
await loadTranslations(initLocale, url.pathname);
107-
};
169+
<Formatter id="common.greeting" values={{ name: "SvelteKit" }} />
170+
<Formatter id="common.farewell" />
108171
```
109172

110-
### 5. Use the Formatter component in your application
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.
111176

112-
The `<Formatter>` component takes in an id which uses the loader key and the key value in the JSON oject to reference the correct line. Props are the variables passed to the Messageformat string.
177+
The `values` prop is optional if your MF2 string does not require any variables.
113178

114-
```ts
115-
<script>
116-
import { setLocale } from "$lib/translations";
117-
import { Formatter } from "sveltekit-mf2";
179+
## Switching locales
118180

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";
119188
120189
function switchToEnglish() {
121190
setLocale("en");
@@ -127,32 +196,29 @@ The `<Formatter>` component takes in an id which uses the loader key and the key
127196
</script>
128197
129198
<div>
130-
<Formatter id="common.test" values={{ world: "SvelteKit" }} />
131-
// values is optional
132-
<Formatter id="common.bye" />
133-
134-
<button onclick={switchToEnglish}>english</button>
135-
<button onclick={switchToSpanish}>spanish</button>
199+
<button onclick={switchToEnglish}>English</button>
200+
<button onclick={switchToSpanish}>Spanish</button>
136201
</div>
137202
```
138203

139-
### References
204+
## Further reading
205+
206+
- [@sveltekit-i18n/base documentation](https://github.com/sveltekit-i18n/base)
140207

141-
[Message Format 2](https://messageformat.unicode.org/)
142-
[sveltekit-i18n/base](https://github.com/sveltekit-i18n/base)
208+
## Reference docs
143209

144-
#### Provider
210+
This package exports two main components: a provider to set up the i18n context,
211+
and a formatter component to render localized strings.
145212

146-
##### `<FormatterProvider>`
213+
### `<FormatterProvider>`
147214

148215
Props:
149-
`t` - The `t` function from the `i18n` object
150216

151-
#### Component
217+
- `t` - The `t` function from the `i18n` object
152218

153-
###### `<Formatter>`
219+
### `<Formatter>`
154220

155221
Props:
156222

157223
- `id: string` - Translation key (e.g., "common.greeting")
158-
- `values: Record<string, any>` - Variables to interpolate
224+
- `values?: Record<string, any>` - Variables to interpolate into the message

0 commit comments

Comments
 (0)