@sveltebase/i18n 0.2.3 → 0.3.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.
Files changed (2) hide show
  1. package/README.md +334 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,334 @@
1
+ # `@sveltebase/i18n`
2
+
3
+ Simple i18n utilities for Svelte 5 apps.
4
+
5
+ `@sveltebase/i18n` gives you a small API for:
6
+
7
+ - defining your supported languages
8
+ - storing the active locale
9
+ - reading translations in components
10
+ - formatting dates and times for the current locale
11
+
12
+ It is designed to stay lightweight and work nicely with Svelte 5 runes.
13
+
14
+ ## Install
15
+
16
+ Install the package with Bun:
17
+
18
+ ```bash
19
+ bun add @sveltebase/i18n
20
+ ```
21
+
22
+ ## What it exports
23
+
24
+ - `createI18n`
25
+ - `getTranslations`
26
+ - `getFormat`
27
+
28
+ ## Quick start
29
+
30
+ Create a shared i18n module:
31
+
32
+ ```ts
33
+ import { createI18n } from "@sveltebase/i18n";
34
+
35
+ export const languages = [
36
+ {
37
+ code: "en",
38
+ label: "English",
39
+ messages: {
40
+ "app-title": "My app",
41
+ "welcome": "Welcome, {name}",
42
+ "just-now": "Just now",
43
+ "minutes-ago": "{minutes} minutes ago",
44
+ "today-at": "Today at {time}",
45
+ "yesterday-at": "Yesterday at {time}"
46
+ }
47
+ },
48
+ {
49
+ code: "uz",
50
+ label: "O‘zbekcha",
51
+ messages: {
52
+ "app-title": "Mening ilovam",
53
+ "welcome": "Xush kelibsiz, {name}",
54
+ "just-now": "Hozirgina",
55
+ "minutes-ago": "{minutes} daqiqa oldin",
56
+ "today-at": "Bugun {time} da",
57
+ "yesterday-at": "Kecha {time} da"
58
+ }
59
+ }
60
+ ] as const;
61
+
62
+ export const i18n = createI18n(languages, "locale");
63
+ ```
64
+
65
+ Then initialize it before using translations or formatters.
66
+
67
+ If you already have the request cookies available during the initial render, pass them to `init(cookies)` immediately. That lets the package restore the saved locale before your UI reads translations, so the correct language loads right away instead of first rendering with the fallback locale and switching later.
68
+
69
+ ```ts
70
+ import { i18n } from "./i18n";
71
+
72
+ i18n.init(cookies);
73
+ ```
74
+
75
+ ## Basic usage in a Svelte component
76
+
77
+ ```svelte
78
+ <script lang="ts">
79
+ import { getTranslations, getFormat } from "@sveltebase/i18n";
80
+ import { i18n } from "$lib/i18n";
81
+
82
+ const t = getTranslations();
83
+ const format = getFormat();
84
+
85
+ function switchLocale(locale: string) {
86
+ i18n.locale = locale;
87
+ }
88
+ </script>
89
+
90
+ <h1>{t("app-title")}</h1>
91
+ <p>{t("welcome", { name: "Jane" })}</p>
92
+ <p>{format(new Date(), { preset: "full", withTime: true })}</p>
93
+
94
+ <button onclick={() => switchLocale("en")}>English</button>
95
+ <button onclick={() => switchLocale("uz")}>O‘zbekcha</button>
96
+ ```
97
+
98
+ ## Creating your language list
99
+
100
+ Each language should have:
101
+
102
+ - `code`: locale code
103
+ - `label`: readable language name
104
+ - `messages`: translation dictionary
105
+
106
+ Example:
107
+
108
+ ```ts
109
+ const languages = [
110
+ {
111
+ code: "en",
112
+ label: "English",
113
+ messages: {
114
+ "app-title": "My app",
115
+ "nav.home": "Home",
116
+ "nav.settings": "Settings"
117
+ }
118
+ },
119
+ {
120
+ code: "uz",
121
+ label: "O‘zbekcha",
122
+ messages: {
123
+ "app-title": "Mening ilovam",
124
+ "nav.home": "Bosh sahifa",
125
+ "nav.settings": "Sozlamalar"
126
+ }
127
+ }
128
+ ] as const;
129
+ ```
130
+
131
+ You can also import messages from JSON or split them across files if that fits your app better.
132
+
133
+ ## Initialization
134
+
135
+ Call `init()` before using `getTranslations()` or `getFormat()`.
136
+
137
+ ### Without cookies
138
+
139
+ If you do not have cookies available yet, you can initialize normally:
140
+
141
+ ```ts
142
+ import { i18n } from "$lib/i18n";
143
+
144
+ i18n.init();
145
+ ```
146
+
147
+ ### With cookies in SvelteKit for faster first render
148
+
149
+ In SvelteKit, the recommended approach is to load all cookies in `+layout.server.ts`, return them from `load`, and then pass that data to `i18n.init(...)` in `+layout.svelte`.
150
+
151
+ This lets `@sveltebase/i18n` restore the saved locale before your UI reads translations, so the correct language is available immediately and you avoid rendering the fallback language first.
152
+
153
+ In `+layout.server.ts`:
154
+
155
+ ```ts
156
+ export function load({ cookies }) {
157
+ return {
158
+ cookies: cookies.getAll()
159
+ };
160
+ }
161
+ ```
162
+
163
+ Then in `+layout.svelte`:
164
+
165
+ ```svelte
166
+ <script lang="ts">
167
+ import { i18n } from "$lib/i18n";
168
+
169
+ let { data } = $props();
170
+
171
+ i18n.init(data.cookies);
172
+ </script>
173
+
174
+ <slot />
175
+ ```
176
+
177
+ The value passed to `i18n.init(...)` should be an array of cookie objects in this shape:
178
+
179
+ ```ts
180
+ type Cookie = {
181
+ name: string;
182
+ value: string;
183
+ };
184
+ ```
185
+
186
+ ## API
187
+
188
+ ## `createI18n(languages, localeStorageKey?)`
189
+
190
+ Creates an i18n instance.
191
+
192
+ ### Parameters
193
+
194
+ - `languages`: an array of language definitions
195
+ - `localeStorageKey?`: the key used to persist the locale, defaults to `"locale"`
196
+
197
+ ### Returns
198
+
199
+ An object with:
200
+
201
+ - `languages`
202
+ - `locale`
203
+ - `currentLanguage`
204
+ - `init(cookies?)`
205
+
206
+ ### Example
207
+
208
+ ```ts
209
+ import { createI18n } from "@sveltebase/i18n";
210
+
211
+ const languages = [
212
+ {
213
+ code: "en",
214
+ label: "English",
215
+ messages: {
216
+ hello: "Hello"
217
+ }
218
+ },
219
+ {
220
+ code: "uz",
221
+ label: "O‘zbekcha",
222
+ messages: {
223
+ hello: "Salom"
224
+ }
225
+ }
226
+ ] as const;
227
+
228
+ const i18n = createI18n(languages, "locale");
229
+ ```
230
+
231
+ ## `getTranslations()`
232
+
233
+ Returns a translation function for the current locale.
234
+
235
+ ### Example
236
+
237
+ ```ts
238
+ import { getTranslations } from "@sveltebase/i18n";
239
+
240
+ const t = getTranslations();
241
+
242
+ t("hello");
243
+ t("welcome", { name: "Jane" });
244
+ ```
245
+
246
+ ## `getFormat()`
247
+
248
+ Returns a formatter function for locale-aware display.
249
+
250
+ ### Example
251
+
252
+ ```ts
253
+ import { getFormat } from "@sveltebase/i18n";
254
+
255
+ const format = getFormat();
256
+
257
+ format(new Date(), { preset: "full" });
258
+ format(new Date(), { preset: "custom", withTime: true });
259
+ format("13:45:00", { preset: "timestring" });
260
+ ```
261
+
262
+ ## Locale switching
263
+
264
+ You can switch the active locale by assigning to `i18n.locale`:
265
+
266
+ ```ts
267
+ i18n.locale = "en";
268
+ ```
269
+
270
+ You can also read the current language object:
271
+
272
+ ```ts
273
+ console.log(i18n.currentLanguage.label);
274
+ ```
275
+
276
+ ## Formatting presets
277
+
278
+ `getFormat()` supports these presets:
279
+
280
+ - `default`
281
+ - `custom`
282
+ - `birthday`
283
+ - `month`
284
+ - `timestring`
285
+ - `full`
286
+
287
+ ### Example
288
+
289
+ ```ts
290
+ const format = getFormat();
291
+
292
+ format(new Date(), { preset: "month" });
293
+ format(new Date(), { preset: "birthday" });
294
+ format(new Date(), { preset: "full", withTime: true });
295
+ format("08:30:00", { preset: "timestring" });
296
+ ```
297
+
298
+ ## Type safety
299
+
300
+ When your language array is declared with `as const`, locale codes are inferred automatically.
301
+
302
+ ```ts
303
+ const languages = [
304
+ {
305
+ code: "en",
306
+ label: "English",
307
+ messages: { hello: "Hello" }
308
+ },
309
+ {
310
+ code: "uz",
311
+ label: "O‘zbekcha",
312
+ messages: { hello: "Salom" }
313
+ }
314
+ ] as const;
315
+ ```
316
+
317
+ That improves typing for values like:
318
+
319
+ - `i18n.locale`
320
+ - `i18n.currentLanguage`
321
+ - language code parameters in your own functions
322
+
323
+ ## Notes
324
+
325
+ - Call `init()` before using `getTranslations()` or `getFormat()`.
326
+ - Passing cookies into `init(cookies)` during the initial render helps the correct locale load faster and avoids rendering the fallback language first.
327
+ - The first language in the array is used as the fallback locale.
328
+ - Locale state is persisted using `@sveltebase/state`.
329
+ - Date formatting includes locale-specific behavior for Uzbek.
330
+ - This package is intended for Svelte 5 apps.
331
+
332
+ ## License
333
+
334
+ ISC
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltebase/i18n",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -18,7 +18,7 @@
18
18
  }
19
19
  },
20
20
  "dependencies": {
21
- "@sveltebase/state": "0.2.3",
21
+ "@sveltebase/state": "0.3.0",
22
22
  "date-fns": "^4.1.0",
23
23
  "use-intl": "^4.4.0",
24
24
  "zod": "^4.1.11"