@better-i18n/use-intl 0.1.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.
- package/README.md +221 -0
- package/dist/components.d.ts +40 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +33 -0
- package/dist/components.js.map +1 -0
- package/dist/context.d.ts +27 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +34 -0
- package/dist/context.js.map +1 -0
- package/dist/hooks.d.ts +49 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +58 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/provider.d.ts +38 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +126 -0
- package/dist/provider.js.map +1 -0
- package/dist/server.d.ts +107 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +109 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# @better-i18n/use-intl
|
|
2
|
+
|
|
3
|
+
Better i18n integration for [use-intl](https://github.com/amannn/next-intl/tree/main/packages/use-intl) - perfect for React, TanStack Start, and any JavaScript framework.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 **CDN-powered** - Fetch translations from Better i18n CDN
|
|
8
|
+
- âš¡ **SSR Ready** - Full server-side rendering support for TanStack Start
|
|
9
|
+
- 🔄 **Dynamic Loading** - Load messages on-demand per locale
|
|
10
|
+
- 🎯 **Type Safe** - Full TypeScript support
|
|
11
|
+
- 🪶 **Lightweight** - Built on use-intl (~2KB)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @better-i18n/use-intl use-intl
|
|
17
|
+
# or
|
|
18
|
+
bun add @better-i18n/use-intl use-intl
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### Client-Side (CSR)
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { BetterI18nProvider, useTranslations } from '@better-i18n/use-intl'
|
|
27
|
+
|
|
28
|
+
function App() {
|
|
29
|
+
return (
|
|
30
|
+
<BetterI18nProvider
|
|
31
|
+
project="your-org/your-project"
|
|
32
|
+
locale="en"
|
|
33
|
+
>
|
|
34
|
+
<HomePage />
|
|
35
|
+
</BetterI18nProvider>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function HomePage() {
|
|
40
|
+
const t = useTranslations('home')
|
|
41
|
+
return <h1>{t('title')}</h1>
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Server-Side (TanStack Start)
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
// routes/__root.tsx
|
|
49
|
+
import { createRootRoute } from '@tanstack/react-router'
|
|
50
|
+
import { BetterI18nProvider } from '@better-i18n/use-intl'
|
|
51
|
+
import { getMessages } from '@better-i18n/use-intl/server'
|
|
52
|
+
|
|
53
|
+
export const Route = createRootRoute({
|
|
54
|
+
loader: async ({ context }) => {
|
|
55
|
+
const messages = await getMessages({
|
|
56
|
+
project: 'your-org/your-project',
|
|
57
|
+
locale: context.locale,
|
|
58
|
+
})
|
|
59
|
+
return { messages }
|
|
60
|
+
},
|
|
61
|
+
component: RootComponent,
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
function RootComponent() {
|
|
65
|
+
const { messages } = Route.useLoaderData()
|
|
66
|
+
const { locale } = Route.useRouteContext()
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<BetterI18nProvider
|
|
70
|
+
project="your-org/your-project"
|
|
71
|
+
locale={locale}
|
|
72
|
+
messages={messages}
|
|
73
|
+
>
|
|
74
|
+
<Outlet />
|
|
75
|
+
</BetterI18nProvider>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## API Reference
|
|
81
|
+
|
|
82
|
+
### Components
|
|
83
|
+
|
|
84
|
+
#### `<BetterI18nProvider>`
|
|
85
|
+
|
|
86
|
+
Main provider that combines Better i18n CDN with use-intl.
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
<BetterI18nProvider
|
|
90
|
+
project="org/project" // Required: Better i18n project
|
|
91
|
+
locale="en" // Required: Current locale
|
|
92
|
+
messages={messages} // Optional: Pre-loaded messages (SSR)
|
|
93
|
+
timeZone="Europe/Berlin" // Optional: Timezone for formatting
|
|
94
|
+
now={new Date()} // Optional: Current time (SSR)
|
|
95
|
+
onLocaleChange={(l) => {}} // Optional: Locale change callback
|
|
96
|
+
>
|
|
97
|
+
{children}
|
|
98
|
+
</BetterI18nProvider>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Hooks
|
|
102
|
+
|
|
103
|
+
#### `useTranslations(namespace?)`
|
|
104
|
+
|
|
105
|
+
Access translations (re-exported from use-intl).
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
const t = useTranslations('common')
|
|
109
|
+
t('greeting', { name: 'World' }) // "Hello, World!"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### `useLocale()`
|
|
113
|
+
|
|
114
|
+
Get and set the current locale.
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
const { locale, setLocale, isLoading } = useLocale()
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### `useLanguages()`
|
|
121
|
+
|
|
122
|
+
Get available languages with metadata.
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
const { languages, isLoading } = useLanguages()
|
|
126
|
+
// [{ code: 'en', name: 'English', nativeName: 'English', flagUrl: '...' }]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### `useBetterI18n()`
|
|
130
|
+
|
|
131
|
+
Access the full Better i18n context.
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
const { locale, setLocale, languages, isLoadingMessages, project } = useBetterI18n()
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### `useFormatter()`
|
|
138
|
+
|
|
139
|
+
Format dates, numbers, and lists (re-exported from use-intl).
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
const format = useFormatter()
|
|
143
|
+
format.dateTime(new Date(), { dateStyle: 'full' })
|
|
144
|
+
format.number(1000, { style: 'currency', currency: 'USD' })
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Server Utilities
|
|
148
|
+
|
|
149
|
+
Import from `@better-i18n/use-intl/server`:
|
|
150
|
+
|
|
151
|
+
#### `getMessages(config)`
|
|
152
|
+
|
|
153
|
+
Fetch messages for SSR.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
const messages = await getMessages({
|
|
157
|
+
project: 'org/project',
|
|
158
|
+
locale: 'en',
|
|
159
|
+
})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### `getLocales(config)`
|
|
163
|
+
|
|
164
|
+
Get available locale codes.
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
const locales = await getLocales({ project: 'org/project' })
|
|
168
|
+
// ['en', 'tr', 'de']
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### `getLanguages(config)`
|
|
172
|
+
|
|
173
|
+
Get languages with metadata.
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const languages = await getLanguages({ project: 'org/project' })
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### `createServerTranslator(config)`
|
|
180
|
+
|
|
181
|
+
Create translator for non-React contexts (metadata, emails).
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
const t = createServerTranslator({ locale: 'en', messages })
|
|
185
|
+
const title = t('page.title')
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Language Switcher Example
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
import { useLocale, useLanguages } from '@better-i18n/use-intl'
|
|
192
|
+
|
|
193
|
+
function LanguageSwitcher() {
|
|
194
|
+
const { locale, setLocale } = useLocale()
|
|
195
|
+
const { languages, isLoading } = useLanguages()
|
|
196
|
+
|
|
197
|
+
if (isLoading) return <span>Loading...</span>
|
|
198
|
+
|
|
199
|
+
return (
|
|
200
|
+
<select value={locale} onChange={(e) => setLocale(e.target.value)}>
|
|
201
|
+
{languages.map((lang) => (
|
|
202
|
+
<option key={lang.code} value={lang.code}>
|
|
203
|
+
{lang.nativeName}
|
|
204
|
+
</option>
|
|
205
|
+
))}
|
|
206
|
+
</select>
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## TanStack Start Full Example
|
|
212
|
+
|
|
213
|
+
See our [TanStack Start guide](/docs/react/tanstack-start) for a complete example with:
|
|
214
|
+
- Locale middleware
|
|
215
|
+
- URL-based locale detection
|
|
216
|
+
- SEO-friendly routing
|
|
217
|
+
- Hydration without mismatches
|
|
218
|
+
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
MIT
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
2
|
+
export interface LanguageSwitcherProps extends Omit<ComponentProps<"select">, "value" | "onChange" | "children"> {
|
|
3
|
+
/**
|
|
4
|
+
* Render function for custom option display
|
|
5
|
+
*/
|
|
6
|
+
renderOption?: (language: {
|
|
7
|
+
code: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
nativeName?: string;
|
|
10
|
+
flagUrl?: string | null;
|
|
11
|
+
}) => ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* Label for loading state
|
|
14
|
+
*/
|
|
15
|
+
loadingLabel?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Pre-built language switcher component
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* // Basic usage
|
|
23
|
+
* <LanguageSwitcher />
|
|
24
|
+
*
|
|
25
|
+
* // With custom styling
|
|
26
|
+
* <LanguageSwitcher className="my-select" />
|
|
27
|
+
*
|
|
28
|
+
* // Custom option rendering
|
|
29
|
+
* <LanguageSwitcher
|
|
30
|
+
* renderOption={(lang) => (
|
|
31
|
+
* <>
|
|
32
|
+
* {lang.flagUrl && <img src={lang.flagUrl} alt="" />}
|
|
33
|
+
* {lang.nativeName}
|
|
34
|
+
* </>
|
|
35
|
+
* )}
|
|
36
|
+
* />
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function LanguageSwitcher({ renderOption, loadingLabel, ...props }: LanguageSwitcherProps): import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvD,MAAM,WAAW,qBACf,SAAQ,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IACzE;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,KAAK,SAAS,CAAC;IAEhB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,YAAY,EACZ,YAA2B,EAC3B,GAAG,KAAK,EACT,EAAE,qBAAqB,2CAoBvB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useBetterI18n } from "./context";
|
|
4
|
+
/**
|
|
5
|
+
* Pre-built language switcher component
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* // Basic usage
|
|
10
|
+
* <LanguageSwitcher />
|
|
11
|
+
*
|
|
12
|
+
* // With custom styling
|
|
13
|
+
* <LanguageSwitcher className="my-select" />
|
|
14
|
+
*
|
|
15
|
+
* // Custom option rendering
|
|
16
|
+
* <LanguageSwitcher
|
|
17
|
+
* renderOption={(lang) => (
|
|
18
|
+
* <>
|
|
19
|
+
* {lang.flagUrl && <img src={lang.flagUrl} alt="" />}
|
|
20
|
+
* {lang.nativeName}
|
|
21
|
+
* </>
|
|
22
|
+
* )}
|
|
23
|
+
* />
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function LanguageSwitcher({ renderOption, loadingLabel = "Loading...", ...props }) {
|
|
27
|
+
const { locale, setLocale, languages, isLoadingLanguages } = useBetterI18n();
|
|
28
|
+
if (isLoadingLanguages) {
|
|
29
|
+
return (_jsx("select", { disabled: true, ...props, children: _jsx("option", { children: loadingLabel }) }));
|
|
30
|
+
}
|
|
31
|
+
return (_jsx("select", { value: locale, onChange: (e) => setLocale(e.target.value), ...props, children: languages.map((lang) => (_jsx("option", { value: lang.code, children: renderOption ? renderOption(lang) : lang.nativeName || lang.code }, lang.code))) }));
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAoB1C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,YAAY,EACZ,YAAY,GAAG,YAAY,EAC3B,GAAG,KAAK,EACc;IACtB,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,kBAAkB,EAAE,GAAG,aAAa,EAAE,CAAC;IAE7E,IAAI,kBAAkB,EAAE,CAAC;QACvB,OAAO,CACL,iBAAQ,QAAQ,WAAK,KAAK,YACxB,2BAAS,YAAY,GAAU,GACxB,CACV,CAAC;IACJ,CAAC;IAED,OAAO,CACL,iBAAQ,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAM,KAAK,YACzE,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACvB,iBAAwB,KAAK,EAAE,IAAI,CAAC,IAAI,YACrC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,IADtD,IAAI,CAAC,IAAI,CAEb,CACV,CAAC,GACK,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { BetterI18nContextValue } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Context for Better i18n specific state
|
|
4
|
+
*/
|
|
5
|
+
export declare const BetterI18nContext: import("react").Context<BetterI18nContextValue | null>;
|
|
6
|
+
/**
|
|
7
|
+
* Hook to access Better i18n context
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function LanguageSwitcher() {
|
|
12
|
+
* const { locale, setLocale, languages } = useBetterI18n()
|
|
13
|
+
*
|
|
14
|
+
* return (
|
|
15
|
+
* <select value={locale} onChange={(e) => setLocale(e.target.value)}>
|
|
16
|
+
* {languages.map((lang) => (
|
|
17
|
+
* <option key={lang.code} value={lang.code}>
|
|
18
|
+
* {lang.nativeName}
|
|
19
|
+
* </option>
|
|
20
|
+
* ))}
|
|
21
|
+
* </select>
|
|
22
|
+
* )
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function useBetterI18n(): BetterI18nContextValue;
|
|
27
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,iBAAiB,wDAE7B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,IAAI,sBAAsB,CAUtD"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Context for Better i18n specific state
|
|
5
|
+
*/
|
|
6
|
+
export const BetterI18nContext = createContext(null);
|
|
7
|
+
/**
|
|
8
|
+
* Hook to access Better i18n context
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* function LanguageSwitcher() {
|
|
13
|
+
* const { locale, setLocale, languages } = useBetterI18n()
|
|
14
|
+
*
|
|
15
|
+
* return (
|
|
16
|
+
* <select value={locale} onChange={(e) => setLocale(e.target.value)}>
|
|
17
|
+
* {languages.map((lang) => (
|
|
18
|
+
* <option key={lang.code} value={lang.code}>
|
|
19
|
+
* {lang.nativeName}
|
|
20
|
+
* </option>
|
|
21
|
+
* ))}
|
|
22
|
+
* </select>
|
|
23
|
+
* )
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function useBetterI18n() {
|
|
28
|
+
const context = useContext(BetterI18nContext);
|
|
29
|
+
if (!context) {
|
|
30
|
+
throw new Error("[better-i18n] useBetterI18n must be used within a BetterI18nProvider");
|
|
31
|
+
}
|
|
32
|
+
return context;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGlD;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAC5C,IAAI,CACL,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAE9C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,sEAAsE,CACvE,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook to get available languages
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```tsx
|
|
6
|
+
* function LanguageList() {
|
|
7
|
+
* const { languages, isLoading } = useLanguages()
|
|
8
|
+
*
|
|
9
|
+
* if (isLoading) return <div>Loading...</div>
|
|
10
|
+
*
|
|
11
|
+
* return (
|
|
12
|
+
* <ul>
|
|
13
|
+
* {languages.map((lang) => (
|
|
14
|
+
* <li key={lang.code}>
|
|
15
|
+
* {lang.nativeName} ({lang.code})
|
|
16
|
+
* </li>
|
|
17
|
+
* ))}
|
|
18
|
+
* </ul>
|
|
19
|
+
* )
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function useLanguages(): {
|
|
24
|
+
languages: import("packages/i18n-core/dist").LanguageOption[];
|
|
25
|
+
isLoading: boolean;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Hook to get and set current locale
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* function LocaleSwitcher() {
|
|
33
|
+
* const { locale, setLocale } = useLocale()
|
|
34
|
+
*
|
|
35
|
+
* return (
|
|
36
|
+
* <button onClick={() => setLocale(locale === 'en' ? 'tr' : 'en')}>
|
|
37
|
+
* Current: {locale}
|
|
38
|
+
* </button>
|
|
39
|
+
* )
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function useLocale(): {
|
|
44
|
+
locale: string;
|
|
45
|
+
setLocale: (locale: string) => void;
|
|
46
|
+
isLoading: boolean;
|
|
47
|
+
};
|
|
48
|
+
export { useTranslations, useFormatter, useMessages, useNow, useTimeZone, useLocale as useIntlLocale, } from "use-intl";
|
|
49
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY;;;EAO3B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS;;;;EAQxB;AAGD,OAAO,EACL,eAAe,EACf,YAAY,EACZ,WAAW,EACX,MAAM,EACN,WAAW,EACX,SAAS,IAAI,aAAa,GAC3B,MAAM,UAAU,CAAC"}
|
package/dist/hooks.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useBetterI18n } from "./context";
|
|
3
|
+
/**
|
|
4
|
+
* Hook to get available languages
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* function LanguageList() {
|
|
9
|
+
* const { languages, isLoading } = useLanguages()
|
|
10
|
+
*
|
|
11
|
+
* if (isLoading) return <div>Loading...</div>
|
|
12
|
+
*
|
|
13
|
+
* return (
|
|
14
|
+
* <ul>
|
|
15
|
+
* {languages.map((lang) => (
|
|
16
|
+
* <li key={lang.code}>
|
|
17
|
+
* {lang.nativeName} ({lang.code})
|
|
18
|
+
* </li>
|
|
19
|
+
* ))}
|
|
20
|
+
* </ul>
|
|
21
|
+
* )
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function useLanguages() {
|
|
26
|
+
const { languages, isLoadingLanguages } = useBetterI18n();
|
|
27
|
+
return {
|
|
28
|
+
languages,
|
|
29
|
+
isLoading: isLoadingLanguages,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Hook to get and set current locale
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* function LocaleSwitcher() {
|
|
38
|
+
* const { locale, setLocale } = useLocale()
|
|
39
|
+
*
|
|
40
|
+
* return (
|
|
41
|
+
* <button onClick={() => setLocale(locale === 'en' ? 'tr' : 'en')}>
|
|
42
|
+
* Current: {locale}
|
|
43
|
+
* </button>
|
|
44
|
+
* )
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export function useLocale() {
|
|
49
|
+
const { locale, setLocale, isLoadingMessages } = useBetterI18n();
|
|
50
|
+
return {
|
|
51
|
+
locale,
|
|
52
|
+
setLocale,
|
|
53
|
+
isLoading: isLoadingMessages,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// Re-export use-intl hooks for convenience
|
|
57
|
+
export { useTranslations, useFormatter, useMessages, useNow, useTimeZone, useLocale as useIntlLocale, } from "use-intl";
|
|
58
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,GAAG,aAAa,EAAE,CAAC;IAE1D,OAAO;QACL,SAAS;QACT,SAAS,EAAE,kBAAkB;KAC9B,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,SAAS;IACvB,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,aAAa,EAAE,CAAC;IAEjE,OAAO;QACL,MAAM;QACN,SAAS;QACT,SAAS,EAAE,iBAAiB;KAC7B,CAAC;AACJ,CAAC;AAED,2CAA2C;AAC3C,OAAO,EACL,eAAe,EACf,YAAY,EACZ,WAAW,EACX,MAAM,EACN,WAAW,EACX,SAAS,IAAI,aAAa,GAC3B,MAAM,UAAU,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { BetterI18nProvider } from "./provider";
|
|
2
|
+
export type { BetterI18nProviderProps } from "./provider";
|
|
3
|
+
export { useBetterI18n } from "./context";
|
|
4
|
+
export { useLanguages, useLocale, useTranslations, useFormatter, useMessages, useNow, useTimeZone, } from "./hooks";
|
|
5
|
+
export { LanguageSwitcher } from "./components";
|
|
6
|
+
export type { LanguageSwitcherProps } from "./components";
|
|
7
|
+
export type { Messages, BetterI18nProviderConfig, BetterI18nContextValue, } from "./types";
|
|
8
|
+
export { IntlProvider } from "use-intl";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAG1D,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,YAAY,EACZ,SAAS,EAET,eAAe,EACf,YAAY,EACZ,WAAW,EACX,MAAM,EACN,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAG1D,YAAY,EACV,QAAQ,EACR,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Provider
|
|
2
|
+
export { BetterI18nProvider } from "./provider";
|
|
3
|
+
// Context & Hooks
|
|
4
|
+
export { useBetterI18n } from "./context";
|
|
5
|
+
export { useLanguages, useLocale,
|
|
6
|
+
// Re-exported from use-intl
|
|
7
|
+
useTranslations, useFormatter, useMessages, useNow, useTimeZone, } from "./hooks";
|
|
8
|
+
// Components
|
|
9
|
+
export { LanguageSwitcher } from "./components";
|
|
10
|
+
// Re-export commonly used use-intl components
|
|
11
|
+
export { IntlProvider } from "use-intl";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhD,kBAAkB;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,YAAY,EACZ,SAAS;AACT,4BAA4B;AAC5B,eAAe,EACf,YAAY,EACZ,WAAW,EACX,MAAM,EACN,WAAW,GACZ,MAAM,SAAS,CAAC;AAEjB,aAAa;AACb,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAUhD,8CAA8C;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { BetterI18nProviderConfig } from "./types";
|
|
3
|
+
export interface BetterI18nProviderProps extends BetterI18nProviderConfig {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Provider component that combines Better i18n CDN with use-intl
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* // Basic usage (CSR - fetches messages on client)
|
|
12
|
+
* function App() {
|
|
13
|
+
* return (
|
|
14
|
+
* <BetterI18nProvider
|
|
15
|
+
* project="acme/dashboard"
|
|
16
|
+
* locale="en"
|
|
17
|
+
* >
|
|
18
|
+
* <MyComponent />
|
|
19
|
+
* </BetterI18nProvider>
|
|
20
|
+
* )
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* // SSR usage (pre-loaded messages)
|
|
24
|
+
* function App({ locale, messages }) {
|
|
25
|
+
* return (
|
|
26
|
+
* <BetterI18nProvider
|
|
27
|
+
* project="acme/dashboard"
|
|
28
|
+
* locale={locale}
|
|
29
|
+
* messages={messages}
|
|
30
|
+
* >
|
|
31
|
+
* <MyComponent />
|
|
32
|
+
* </BetterI18nProvider>
|
|
33
|
+
* )
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function BetterI18nProvider({ children, project, locale: initialLocale, messages: initialMessages, timeZone, now, onLocaleChange, onError, cdnBaseUrl, debug, logLevel, fetch: customFetch, }: BetterI18nProviderProps): import("react/jsx-runtime").JSX.Element | null;
|
|
38
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAIA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,wBAAwB,EAAY,MAAM,SAAS,CAAC;AAElE,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,OAAO,EACP,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EACR,GAAG,EACH,cAAc,EACd,OAAO,EACP,UAAU,EACV,KAAK,EACL,QAAQ,EACR,KAAK,EAAE,WAAW,GACnB,EAAE,uBAAuB,kDA6HzB"}
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createI18nCore } from "@better-i18n/i18n-core";
|
|
4
|
+
import { useCallback, useEffect, useMemo, useState, } from "react";
|
|
5
|
+
import { IntlProvider } from "use-intl";
|
|
6
|
+
import { BetterI18nContext } from "./context";
|
|
7
|
+
/**
|
|
8
|
+
* Provider component that combines Better i18n CDN with use-intl
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* // Basic usage (CSR - fetches messages on client)
|
|
13
|
+
* function App() {
|
|
14
|
+
* return (
|
|
15
|
+
* <BetterI18nProvider
|
|
16
|
+
* project="acme/dashboard"
|
|
17
|
+
* locale="en"
|
|
18
|
+
* >
|
|
19
|
+
* <MyComponent />
|
|
20
|
+
* </BetterI18nProvider>
|
|
21
|
+
* )
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* // SSR usage (pre-loaded messages)
|
|
25
|
+
* function App({ locale, messages }) {
|
|
26
|
+
* return (
|
|
27
|
+
* <BetterI18nProvider
|
|
28
|
+
* project="acme/dashboard"
|
|
29
|
+
* locale={locale}
|
|
30
|
+
* messages={messages}
|
|
31
|
+
* >
|
|
32
|
+
* <MyComponent />
|
|
33
|
+
* </BetterI18nProvider>
|
|
34
|
+
* )
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function BetterI18nProvider({ children, project, locale: initialLocale, messages: initialMessages, timeZone, now, onLocaleChange, onError, cdnBaseUrl, debug, logLevel, fetch: customFetch, }) {
|
|
39
|
+
const [locale, setLocaleState] = useState(initialLocale);
|
|
40
|
+
const [messages, setMessages] = useState(initialMessages);
|
|
41
|
+
const [languages, setLanguages] = useState([]);
|
|
42
|
+
const [isLoadingMessages, setIsLoadingMessages] = useState(!initialMessages);
|
|
43
|
+
const [isLoadingLanguages, setIsLoadingLanguages] = useState(true);
|
|
44
|
+
// Create i18n core instance
|
|
45
|
+
const i18nCore = useMemo(() => createI18nCore({
|
|
46
|
+
project,
|
|
47
|
+
defaultLocale: initialLocale,
|
|
48
|
+
cdnBaseUrl,
|
|
49
|
+
debug,
|
|
50
|
+
logLevel,
|
|
51
|
+
fetch: customFetch,
|
|
52
|
+
}), [project, initialLocale, cdnBaseUrl, debug, logLevel, customFetch]);
|
|
53
|
+
// Load languages on mount
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
let cancelled = false;
|
|
56
|
+
const loadLanguages = async () => {
|
|
57
|
+
try {
|
|
58
|
+
const langs = await i18nCore.getLanguages();
|
|
59
|
+
if (!cancelled) {
|
|
60
|
+
setLanguages(langs);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error("[better-i18n] Failed to load languages:", error);
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
if (!cancelled) {
|
|
68
|
+
setIsLoadingLanguages(false);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
loadLanguages();
|
|
73
|
+
return () => {
|
|
74
|
+
cancelled = true;
|
|
75
|
+
};
|
|
76
|
+
}, [i18nCore]);
|
|
77
|
+
// Load messages when locale changes (if not pre-loaded)
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
// Skip if we have initial messages for the current locale
|
|
80
|
+
if (initialMessages && locale === initialLocale) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
let cancelled = false;
|
|
84
|
+
const loadMessages = async () => {
|
|
85
|
+
setIsLoadingMessages(true);
|
|
86
|
+
try {
|
|
87
|
+
const msgs = await i18nCore.getMessages(locale);
|
|
88
|
+
if (!cancelled) {
|
|
89
|
+
setMessages(msgs);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error(`[better-i18n] Failed to load messages for locale "${locale}":`, error);
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
if (!cancelled) {
|
|
97
|
+
setIsLoadingMessages(false);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
loadMessages();
|
|
102
|
+
return () => {
|
|
103
|
+
cancelled = true;
|
|
104
|
+
};
|
|
105
|
+
}, [locale, i18nCore, initialMessages, initialLocale]);
|
|
106
|
+
// Locale change handler
|
|
107
|
+
const setLocale = useCallback((newLocale) => {
|
|
108
|
+
setLocaleState(newLocale);
|
|
109
|
+
onLocaleChange?.(newLocale);
|
|
110
|
+
}, [onLocaleChange]);
|
|
111
|
+
// Context value
|
|
112
|
+
const contextValue = useMemo(() => ({
|
|
113
|
+
locale,
|
|
114
|
+
setLocale,
|
|
115
|
+
languages,
|
|
116
|
+
isLoadingLanguages,
|
|
117
|
+
isLoadingMessages,
|
|
118
|
+
project,
|
|
119
|
+
}), [locale, setLocale, languages, isLoadingLanguages, isLoadingMessages, project]);
|
|
120
|
+
// Don't render until we have messages
|
|
121
|
+
if (!messages) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
return (_jsx(BetterI18nContext.Provider, { value: contextValue, children: _jsx(IntlProvider, { locale: locale, messages: messages, timeZone: timeZone, now: now, onError: onError, children: children }) }));
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { I18nCoreConfig, LanguageOption } from "@better-i18n/i18n-core";
|
|
2
|
+
import type { Messages } from "./types";
|
|
3
|
+
export interface GetMessagesConfig extends Omit<I18nCoreConfig, "defaultLocale"> {
|
|
4
|
+
/**
|
|
5
|
+
* Locale to fetch messages for
|
|
6
|
+
*/
|
|
7
|
+
locale: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Fetch messages for a locale (server-side)
|
|
11
|
+
*
|
|
12
|
+
* Use this in your server loaders (TanStack Start, Remix, etc.)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* // TanStack Start loader
|
|
17
|
+
* export async function loader({ params }) {
|
|
18
|
+
* const locale = params.locale || 'en'
|
|
19
|
+
* const messages = await getMessages({
|
|
20
|
+
* project: 'acme/dashboard',
|
|
21
|
+
* locale,
|
|
22
|
+
* })
|
|
23
|
+
* return { locale, messages }
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function getMessages(config: GetMessagesConfig): Promise<Messages>;
|
|
28
|
+
/**
|
|
29
|
+
* Fetch available locales (server-side)
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* const locales = await getLocales({ project: 'acme/dashboard' })
|
|
34
|
+
* // ['en', 'tr', 'de', ...]
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function getLocales(config: Omit<I18nCoreConfig, "defaultLocale"> & {
|
|
38
|
+
defaultLocale?: string;
|
|
39
|
+
}): Promise<string[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Fetch available languages with metadata (server-side)
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* const languages = await getLanguages({ project: 'acme/dashboard' })
|
|
46
|
+
* // [{ code: 'en', name: 'English', nativeName: 'English', flagUrl: '...' }, ...]
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function getLanguages(config: Omit<I18nCoreConfig, "defaultLocale"> & {
|
|
50
|
+
defaultLocale?: string;
|
|
51
|
+
}): Promise<LanguageOption[]>;
|
|
52
|
+
/**
|
|
53
|
+
* Create a translator function for use outside React (server-side)
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* const messages = await getMessages({ project: 'acme/dashboard', locale: 'en' })
|
|
58
|
+
* const t = createServerTranslator({ locale: 'en', messages })
|
|
59
|
+
*
|
|
60
|
+
* // Use in metadata, emails, etc.
|
|
61
|
+
* const title = t('page.title')
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function createServerTranslator(config: {
|
|
65
|
+
locale: string;
|
|
66
|
+
messages: Messages;
|
|
67
|
+
namespace?: string;
|
|
68
|
+
}): import("use-intl")._Translator<{
|
|
69
|
+
[x: string]: any;
|
|
70
|
+
}, string>;
|
|
71
|
+
/**
|
|
72
|
+
* Create a formatter for use outside React (server-side)
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* const format = createServerFormatter({ locale: 'en' })
|
|
77
|
+
* const date = format.dateTime(new Date(), { dateStyle: 'full' })
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare function createServerFormatter(config: {
|
|
81
|
+
locale: string;
|
|
82
|
+
timeZone?: string;
|
|
83
|
+
now?: Date;
|
|
84
|
+
}): {
|
|
85
|
+
dateTime: {
|
|
86
|
+
(value: Date | number, options?: import("use-intl").DateTimeFormatOptions): string;
|
|
87
|
+
(value: Date | number, format?: string, options?: import("use-intl").DateTimeFormatOptions): string;
|
|
88
|
+
};
|
|
89
|
+
number: {
|
|
90
|
+
(value: number | bigint, options?: import("use-intl").NumberFormatOptions): string;
|
|
91
|
+
(value: number | bigint, format?: string, options?: import("use-intl").NumberFormatOptions): string;
|
|
92
|
+
};
|
|
93
|
+
relativeTime: {
|
|
94
|
+
(date: number | Date, now?: import("use-intl").RelativeTimeFormatOptions["now"]): string;
|
|
95
|
+
(date: number | Date, options?: import("use-intl").RelativeTimeFormatOptions): string;
|
|
96
|
+
};
|
|
97
|
+
list: {
|
|
98
|
+
<Value extends string | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>>(value: Iterable<Value>, options?: Intl.ListFormatOptions): Value extends string ? string : Iterable<import("react").ReactElement>;
|
|
99
|
+
<Value extends string | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>>(value: Iterable<Value>, format?: string, options?: Intl.ListFormatOptions): Value extends string ? string : Iterable<import("react").ReactElement>;
|
|
100
|
+
};
|
|
101
|
+
dateTimeRange: {
|
|
102
|
+
(start: Date | number, end: Date | number, options?: import("use-intl").DateTimeFormatOptions): string;
|
|
103
|
+
(start: Date | number, end: Date | number, format?: string, options?: import("use-intl").DateTimeFormatOptions): string;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
export { createTranslator, createFormatter } from "use-intl/core";
|
|
107
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC;IAC9E;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAW9E;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACzE,OAAO,CAAC,MAAM,EAAE,CAAC,CAWnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACzE,OAAO,CAAC,cAAc,EAAE,CAAC,CAW3B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;;WAMA;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;;sCAlGiD,CAAC;qCAE3C,CAAC,iBACK,CAAC;;;wCAGC,CAAC;uCAIQ,CAAC,iBAAgC,CAAC;;;iCAQ1C,CAAC;qCAEf,CAAC;;;2JAMmB,CAAC;0JAYf,CAAC,iBAA8B,CAAC;;;0DAKiB,CAAC;yDAIxC,CAAC,iBAAkC,CAAC;;EAyDtD;AAGD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { createI18nCore } from "@better-i18n/i18n-core";
|
|
2
|
+
import { createFormatter, createTranslator } from "use-intl/core";
|
|
3
|
+
/**
|
|
4
|
+
* Fetch messages for a locale (server-side)
|
|
5
|
+
*
|
|
6
|
+
* Use this in your server loaders (TanStack Start, Remix, etc.)
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* // TanStack Start loader
|
|
11
|
+
* export async function loader({ params }) {
|
|
12
|
+
* const locale = params.locale || 'en'
|
|
13
|
+
* const messages = await getMessages({
|
|
14
|
+
* project: 'acme/dashboard',
|
|
15
|
+
* locale,
|
|
16
|
+
* })
|
|
17
|
+
* return { locale, messages }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export async function getMessages(config) {
|
|
22
|
+
const i18n = createI18nCore({
|
|
23
|
+
project: config.project,
|
|
24
|
+
defaultLocale: config.locale,
|
|
25
|
+
cdnBaseUrl: config.cdnBaseUrl,
|
|
26
|
+
debug: config.debug,
|
|
27
|
+
logLevel: config.logLevel,
|
|
28
|
+
fetch: config.fetch,
|
|
29
|
+
});
|
|
30
|
+
return (await i18n.getMessages(config.locale));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Fetch available locales (server-side)
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const locales = await getLocales({ project: 'acme/dashboard' })
|
|
38
|
+
* // ['en', 'tr', 'de', ...]
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export async function getLocales(config) {
|
|
42
|
+
const i18n = createI18nCore({
|
|
43
|
+
project: config.project,
|
|
44
|
+
defaultLocale: config.defaultLocale || "en",
|
|
45
|
+
cdnBaseUrl: config.cdnBaseUrl,
|
|
46
|
+
debug: config.debug,
|
|
47
|
+
logLevel: config.logLevel,
|
|
48
|
+
fetch: config.fetch,
|
|
49
|
+
});
|
|
50
|
+
return i18n.getLocales();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Fetch available languages with metadata (server-side)
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* const languages = await getLanguages({ project: 'acme/dashboard' })
|
|
58
|
+
* // [{ code: 'en', name: 'English', nativeName: 'English', flagUrl: '...' }, ...]
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export async function getLanguages(config) {
|
|
62
|
+
const i18n = createI18nCore({
|
|
63
|
+
project: config.project,
|
|
64
|
+
defaultLocale: config.defaultLocale || "en",
|
|
65
|
+
cdnBaseUrl: config.cdnBaseUrl,
|
|
66
|
+
debug: config.debug,
|
|
67
|
+
logLevel: config.logLevel,
|
|
68
|
+
fetch: config.fetch,
|
|
69
|
+
});
|
|
70
|
+
return i18n.getLanguages();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create a translator function for use outside React (server-side)
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* const messages = await getMessages({ project: 'acme/dashboard', locale: 'en' })
|
|
78
|
+
* const t = createServerTranslator({ locale: 'en', messages })
|
|
79
|
+
*
|
|
80
|
+
* // Use in metadata, emails, etc.
|
|
81
|
+
* const title = t('page.title')
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export function createServerTranslator(config) {
|
|
85
|
+
return createTranslator({
|
|
86
|
+
locale: config.locale,
|
|
87
|
+
messages: config.messages,
|
|
88
|
+
namespace: config.namespace,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create a formatter for use outside React (server-side)
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* const format = createServerFormatter({ locale: 'en' })
|
|
97
|
+
* const date = format.dateTime(new Date(), { dateStyle: 'full' })
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export function createServerFormatter(config) {
|
|
101
|
+
return createFormatter({
|
|
102
|
+
locale: config.locale,
|
|
103
|
+
timeZone: config.timeZone,
|
|
104
|
+
now: config.now,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// Re-export core functions from use-intl for advanced usage
|
|
108
|
+
export { createTranslator, createFormatter } from "use-intl/core";
|
|
109
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAUlE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAyB;IACzD,MAAM,IAAI,GAAG,cAAc,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,MAAM;QAC5B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAC;IAEH,OAAO,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAa,CAAC;AAC7D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAA0E;IAE1E,MAAM,IAAI,GAAG,cAAc,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;QAC3C,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAA0E;IAE1E,MAAM,IAAI,GAAG,cAAc,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;QAC3C,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;AAC7B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAItC;IACC,OAAO,gBAAgB,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAA8D;QAC/E,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAIrC;IACC,OAAO,eAAe,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,GAAG,EAAE,MAAM,CAAC,GAAG;KAChB,CAAC,CAAC;AACL,CAAC;AAED,4DAA4D;AAC5D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { I18nCoreConfig, LanguageOption } from "@better-i18n/i18n-core";
|
|
2
|
+
import type { ComponentProps } from "react";
|
|
3
|
+
import type { IntlProvider } from "use-intl";
|
|
4
|
+
/**
|
|
5
|
+
* Messages type (compatible with use-intl)
|
|
6
|
+
*/
|
|
7
|
+
export type Messages = ComponentProps<typeof IntlProvider>["messages"];
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for BetterI18nProvider
|
|
10
|
+
*/
|
|
11
|
+
export interface BetterI18nProviderConfig extends Omit<I18nCoreConfig, "defaultLocale"> {
|
|
12
|
+
/**
|
|
13
|
+
* Current locale
|
|
14
|
+
*/
|
|
15
|
+
locale: string;
|
|
16
|
+
/**
|
|
17
|
+
* Pre-loaded messages (for SSR hydration)
|
|
18
|
+
*/
|
|
19
|
+
messages?: Messages;
|
|
20
|
+
/**
|
|
21
|
+
* Timezone for date/time formatting
|
|
22
|
+
* @default undefined (uses browser timezone)
|
|
23
|
+
*/
|
|
24
|
+
timeZone?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Current date/time (useful for SSR to prevent hydration mismatches)
|
|
27
|
+
*/
|
|
28
|
+
now?: Date;
|
|
29
|
+
/**
|
|
30
|
+
* Callback when locale changes
|
|
31
|
+
*/
|
|
32
|
+
onLocaleChange?: (locale: string) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Error handler for missing translations
|
|
35
|
+
*/
|
|
36
|
+
onError?: ComponentProps<typeof IntlProvider>["onError"];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Better i18n context value
|
|
40
|
+
*/
|
|
41
|
+
export interface BetterI18nContextValue {
|
|
42
|
+
/**
|
|
43
|
+
* Current locale
|
|
44
|
+
*/
|
|
45
|
+
locale: string;
|
|
46
|
+
/**
|
|
47
|
+
* Change the current locale
|
|
48
|
+
*/
|
|
49
|
+
setLocale: (locale: string) => void;
|
|
50
|
+
/**
|
|
51
|
+
* Available languages with metadata
|
|
52
|
+
*/
|
|
53
|
+
languages: LanguageOption[];
|
|
54
|
+
/**
|
|
55
|
+
* Whether languages are still loading
|
|
56
|
+
*/
|
|
57
|
+
isLoadingLanguages: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Whether messages are still loading
|
|
60
|
+
*/
|
|
61
|
+
isLoadingMessages: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Project identifier
|
|
64
|
+
*/
|
|
65
|
+
project: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Server-side configuration for getMessages
|
|
69
|
+
*/
|
|
70
|
+
export interface GetMessagesConfig extends I18nCoreConfig {
|
|
71
|
+
/**
|
|
72
|
+
* Locale to fetch messages for
|
|
73
|
+
*/
|
|
74
|
+
locale: string;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,wBACf,SAAQ,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC;IAC7C;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,GAAG,CAAC,EAAE,IAAI,CAAC;IAEX;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAE1C;;OAEG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC;CAC1D;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAEpC;;OAEG;IACH,SAAS,EAAE,cAAc,EAAE,CAAC;IAE5B;;OAEG;IACH,kBAAkB,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@better-i18n/use-intl",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Better i18n integration for use-intl (React, TanStack Start)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/better-i18n/better-i18n.git",
|
|
9
|
+
"directory": "packages/use-intl"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/better-i18n/better-i18n/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/better-i18n/better-i18n/tree/main/packages/use-intl",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./server": {
|
|
24
|
+
"types": "./dist/server.d.ts",
|
|
25
|
+
"default": "./dist/server.js"
|
|
26
|
+
},
|
|
27
|
+
"./package.json": "./package.json"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"package.json",
|
|
32
|
+
"README.md"
|
|
33
|
+
],
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"i18n",
|
|
39
|
+
"localization",
|
|
40
|
+
"internationalization",
|
|
41
|
+
"react",
|
|
42
|
+
"tanstack",
|
|
43
|
+
"use-intl",
|
|
44
|
+
"next-intl"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsc",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"clean": "rm -rf dist",
|
|
50
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@better-i18n/i18n-core": "workspace:*"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"react": ">=18.0.0",
|
|
57
|
+
"use-intl": ">=4.0.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@better-i18n/typescript-config": "workspace:*",
|
|
61
|
+
"@types/react": "^19.0.0",
|
|
62
|
+
"react": "^19.0.0",
|
|
63
|
+
"use-intl": "^4.7.0",
|
|
64
|
+
"typescript": "~5.9.2"
|
|
65
|
+
}
|
|
66
|
+
}
|