@zachhandley/ez-i18n 0.3.0 → 0.3.2

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 ADDED
@@ -0,0 +1,88 @@
1
+ # @zachhandley/ez-i18n
2
+
3
+ Cookie-based i18n for Astro. Ships the Astro integration plus the shared runtime stores used by the React/Vue bindings.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @zachhandley/ez-i18n nanostores @nanostores/persistent
9
+ ```
10
+
11
+ ## Astro Setup
12
+
13
+ ```ts
14
+ // astro.config.ts
15
+ import { defineConfig } from 'astro/config';
16
+ import vue from '@astrojs/vue';
17
+ import ezI18n from '@zachhandley/ez-i18n';
18
+
19
+ export default defineConfig({
20
+ integrations: [
21
+ vue(),
22
+ ezI18n({
23
+ locales: ['en', 'es', 'fr'],
24
+ defaultLocale: 'en',
25
+ translations: {
26
+ en: './src/i18n/en.json',
27
+ es: './src/i18n/es.json',
28
+ },
29
+ }),
30
+ ],
31
+ });
32
+ ```
33
+
34
+ Add `EzI18nHead` to your layout to hydrate the locale + translations on the client:
35
+
36
+ ```astro
37
+ ---
38
+ import EzI18nHead from '@zachhandley/ez-i18n/astro';
39
+ const { locale, translations } = Astro.locals;
40
+ ---
41
+
42
+ <html lang={locale}>
43
+ <head>
44
+ <EzI18nHead locale={locale} translations={translations} />
45
+ </head>
46
+ <body><slot /></body>
47
+ </html>
48
+ ```
49
+
50
+ ## Translations
51
+
52
+ Place JSON files per locale (auto-discovered in `public/i18n/` by default):
53
+
54
+ ```json
55
+ {
56
+ "common": {
57
+ "welcome": "Welcome",
58
+ "save": "Save",
59
+ "cancel": "Cancel"
60
+ },
61
+ "auth": {
62
+ "login": "Log in",
63
+ "signup": "Sign up"
64
+ }
65
+ }
66
+ ```
67
+
68
+ Use dot notation and `{placeholder}` interpolation:
69
+
70
+ ```ts
71
+ import { t, locale, setLocale } from 'ez-i18n:runtime';
72
+
73
+ t('common.welcome'); // "Welcome"
74
+ t('auth.signup'); // "Sign up"
75
+ t('common.countdown', { seconds: 5 }); // "Ready in 5 seconds"
76
+ await setLocale('es');
77
+ ```
78
+
79
+ ## Framework Bindings
80
+
81
+ - React: `@zachhandley/ez-i18n-react`
82
+ - Vue 3: `@zachhandley/ez-i18n-vue`
83
+
84
+ Both reuse the runtime stores provided by this package.
85
+
86
+ ## License
87
+
88
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zachhandley/ez-i18n",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -30,7 +30,8 @@
30
30
  },
31
31
  "files": [
32
32
  "dist",
33
- "src"
33
+ "src",
34
+ "README.md"
34
35
  ],
35
36
  "keywords": [
36
37
  "astro",
@@ -43,8 +43,8 @@ const serializedTranslations = JSON.stringify(translations);
43
43
  const locale = script.dataset.ezI18nLocale;
44
44
  const translations = JSON.parse(script.dataset.ezI18nTranslations || '{}');
45
45
 
46
- // Store for runtime initialization
47
- window.__EZ_I18N_INIT__ = { locale, translations };
46
+ // Store for runtime initialization (globalThis is SSR-safe and equals window in browsers)
47
+ globalThis.__EZ_I18N_INIT__ = { locale, translations };
48
48
  })();
49
49
  </script>
50
50
 
@@ -53,10 +53,11 @@ const serializedTranslations = JSON.stringify(translations);
53
53
  import { initLocale, setTranslations } from '@zachhandley/ez-i18n/runtime';
54
54
 
55
55
  // Get initialization data from inline script
56
- const initData = (window as any).__EZ_I18N_INIT__;
56
+ // Note: Don't delete __EZ_I18N_INIT__ here - other bundles (Vue, React)
57
+ // may need to read it to initialize their own store instances
58
+ const initData = (globalThis as any).__EZ_I18N_INIT__;
57
59
  if (initData) {
58
60
  initLocale(initData.locale, initData.translations);
59
61
  setTranslations(initData.translations);
60
- delete (window as any).__EZ_I18N_INIT__;
61
62
  }
62
63
  </script>