@orderly.network/i18n 3.0.4-alpha.2 → 3.0.4-alpha.4
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/dist/{constant-BwPxVQ3H.d.mts → constant-CIx423sl.d.mts} +2 -0
- package/dist/{constant-BwPxVQ3H.d.ts → constant-CIx423sl.d.ts} +2 -0
- package/dist/constant.d.mts +1 -1
- package/dist/constant.d.ts +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +96 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +96 -14
- package/dist/index.mjs.map +1 -1
- package/dist/locale.csv +4 -2
- package/dist/locales/de.json +4 -2
- package/dist/locales/en.json +3 -1
- package/dist/locales/es.json +4 -2
- package/dist/locales/fr.json +4 -2
- package/dist/locales/id.json +4 -2
- package/dist/locales/it.json +4 -2
- package/dist/locales/ja.json +4 -2
- package/dist/locales/ko.json +4 -2
- package/dist/locales/nl.json +4 -2
- package/dist/locales/pl.json +4 -2
- package/dist/locales/pt.json +4 -2
- package/dist/locales/ru.json +4 -2
- package/dist/locales/tc.json +4 -2
- package/dist/locales/tr.json +4 -2
- package/dist/locales/uk.json +4 -2
- package/dist/locales/vi.json +4 -2
- package/dist/locales/zh.json +4 -2
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +38 -1
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +38 -1
- package/dist/utils.mjs.map +1 -1
- package/docs/guide/integration.md +76 -27
- package/package.json +2 -2
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**This guide** documents props, effects, and loading strategies. For **end-to-end copy-paste recipes** (Vite `import.meta.glob`, Next.js/webpack, HTTP `public/`, sync maps, URL sync), use [Examples](./examples.md).
|
|
4
4
|
|
|
5
|
-
**Overview:** `LocaleProvider` composes
|
|
5
|
+
**Overview:** `LocaleProvider` composes `LanguageProvider` (language list, optional HTTP `Backend`, change callbacks) and `I18nextProvider` from react-i18next. All of it uses the package’s singleton `i18n` instance. The default namespace is `translation` (`defaultNS`); see [Package exports](./exports.md).
|
|
6
6
|
|
|
7
7
|
Follow the steps below to integrate localization in your app with the Orderly SDK.
|
|
8
8
|
|
|
@@ -36,10 +36,10 @@ These props are defined on `LocaleProvider` (see `localeProvider.tsx`):
|
|
|
36
36
|
| Prop | Description |
|
|
37
37
|
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
38
38
|
| `locale` | Optional **controlled** locale. When set and different from `i18n.language`, a `useEffect` calls `i18n.changeLanguage(locale)`. |
|
|
39
|
-
| `resource` | Flat messages for
|
|
39
|
+
| `resource` | Flat messages for `defaultNS` (`translation`). Used only when `resources` is not set; requires `locale`. Calls `i18n.addResourceBundle(locale, defaultNS, resource, true, true)`. |
|
|
40
40
|
| `resources` | Static **Resources** map or **AsyncResources**. When set, **registerResources** runs in a `useEffect` (see **Behavior**). Takes precedence over `locale` + `resource`. Same contract as `ExternalLocaleProvider` / `useRegisterExternalResources`. |
|
|
41
41
|
|
|
42
|
-
**Async loader and `ns`:** The `AsyncResources` type is `(lang, ns) => Promise<Record<string, string>>`. When loading goes through
|
|
42
|
+
**Async loader and `ns`:** The `AsyncResources` type is `(lang, ns) => Promise<Record<string, string>>`. When loading goes through `registerResources` (from `LocaleProvider`, `ExternalLocaleProvider`, or `useRegisterExternalResources`), the implementation calls `await resources(localeCode, defaultNS)` — the second argument is **always** `defaultNS` (`translation`), not an arbitrary namespace. Use the parameter if you build URLs; for multiple i18n namespaces, use the i18n API directly.
|
|
43
43
|
|
|
44
44
|
### Inherited from `LanguageProvider`
|
|
45
45
|
|
|
@@ -49,7 +49,7 @@ Pass these through `LocaleProvider` like any other `LanguageProvider` prop:
|
|
|
49
49
|
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
50
50
|
| `backend` | `BackendOptions`: `{ loadPath }` where `loadPath(lang, ns)` returns a URL `string`, `string[]`, or `undefined` for the HTTP `Backend`. Those URLs must resolve to real files (e.g. under `public/`); the package does **not** copy `dist/locales` into your app — sync manually or via a script / hook — see [HTTP backend](./examples.md#http-backend). |
|
|
51
51
|
| `languages` | Full `Language[]` for the switcher; when set as an array, replaces `defaultLanguages`. |
|
|
52
|
-
| `supportedLanguages` | Subset of `LocaleCode[]`; builds the list from
|
|
52
|
+
| `supportedLanguages` | Subset of `LocaleCode[]`; builds the list from `defaultLanguages` entries. |
|
|
53
53
|
| `onLanguageBeforeChanged` | `(lang) => Promise<void>`. **Runs first**; then the internal `Backend` loads the next language (`loadLanguage(lang, defaultNS)`). Use for prep work before HTTP loads. |
|
|
54
54
|
| `onLanguageChanged` | `(lang) => Promise<void>` — notification on the language-change path. |
|
|
55
55
|
| `convertDetectedLanguage` | `(browserLang: string) => LocaleCode` — optional mapping from the detector to your supported codes. |
|
|
@@ -57,16 +57,16 @@ Pass these through `LocaleProvider` like any other `LanguageProvider` prop:
|
|
|
57
57
|
|
|
58
58
|
### Behavior (effects)
|
|
59
59
|
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
60
|
+
- **`resources` set:** `registerResources(resources, locale ?? currentLocale)` runs when `locale`, `resource`, `resources`, or the current locale from `useLocaleCode` changes. Static maps register every locale entry; async loaders fetch for the active locale code.
|
|
61
|
+
- **`resources` unset and `resource` + `locale`:** merges the flat bundle for that locale into `defaultNS`.
|
|
62
|
+
- **`locale` prop:** separate effect — if `locale` is set and differs from `i18n.language`, `i18n.changeLanguage(locale)` runs.
|
|
63
63
|
|
|
64
|
-
Prefer **one** primary loading approach per app (**HTTP `backend`** vs **static/async `resources`** vs
|
|
64
|
+
Prefer **one** primary loading approach per app (**HTTP `backend`** vs **static/async `resources`** vs **`locale` + `resource`**) to avoid overlapping bundles. You can pass `resources` on `LocaleProvider` instead of `ExternalLocaleProvider` — same registration path. Use `useRegisterExternalResources` to avoid an extra wrapper (stable `resources` reference recommended).
|
|
65
65
|
|
|
66
66
|
### Loading strategies (quick reference)
|
|
67
67
|
|
|
68
68
|
- **HTTP:** `backend={{ loadPath }}` — load JSON from URLs (e.g. files under `public/`). You must **place** those JSON files on disk (or CDN): **manually** copy from `node_modules/.../i18n/dist/locales`, or run a **copy script** / **Husky** hook (`npm run copyLocales`, etc.) as in [HTTP backend](./examples.md#http-backend).
|
|
69
|
-
- **Bundled:** `resources` as a static map or
|
|
69
|
+
- **Bundled:** `resources` as a static map or `AsyncResources`. Recipes: [Async resources (Vite)](./examples.md#async-resources-vite) · [Async resources (Next.js and webpack)](./examples.md#async-resources-nextjs-and-webpack) · [Sync resources](./examples.md#sync-resources).
|
|
70
70
|
- **Controlled single bundle:** `locale` + `resource` when you inject one flat table for one language.
|
|
71
71
|
- **Host / external bundles:** `ExternalLocaleProvider` or `useRegisterExternalResources` — same `Resources` / `AsyncResources` as `LocaleProvider.resources`.
|
|
72
72
|
|
|
@@ -78,7 +78,7 @@ Prefer **one** primary loading approach per app (**HTTP `backend`** vs **static/
|
|
|
78
78
|
|
|
79
79
|
### Supported locales
|
|
80
80
|
|
|
81
|
-
We currently support **17** locales. The table order matches
|
|
81
|
+
We currently support **17** locales. The table order matches `defaultLanguages` in the package (`constant`).
|
|
82
82
|
|
|
83
83
|
| Locale Code | Language |
|
|
84
84
|
| ----------- | ------------------- |
|
|
@@ -109,7 +109,7 @@ We currently support **17** locales. The table order matches `**defaultLanguages
|
|
|
109
109
|
|
|
110
110
|
You can translate SDK strings and add strings for your own UI.
|
|
111
111
|
|
|
112
|
-
- Use the
|
|
112
|
+
- Use the `extend.` key prefix for custom keys so they stay distinct from built-in keys (and align with tooling such as `separateJson` in the [CLI](./cli.md)).
|
|
113
113
|
|
|
114
114
|
```json
|
|
115
115
|
{
|
|
@@ -119,44 +119,93 @@ You can translate SDK strings and add strings for your own UI.
|
|
|
119
119
|
|
|
120
120
|
## 4. Integrate external resources
|
|
121
121
|
|
|
122
|
-
Use this when strings live outside this package (another bundle, CDN, or host app).
|
|
122
|
+
Use this when strings live outside this package (another bundle, CDN, or host app). `LocaleProvider` with `resources`, `ExternalLocaleProvider`, and `useRegisterExternalResources` all call the same `registerResources` helper.
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
### Host app vs external package
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
Pick the integration point based on who owns the React root:
|
|
127
|
+
|
|
128
|
+
- **Host apps:** mount `LocaleProvider` once at the app/orderly root. Pass `backend`, `resources`, or `locale` + `resource` there. For Vite/Next/webpack app-level recipes, see [Examples](./examples.md).
|
|
129
|
+
- **External SDK/plugin packages:** export a package-local provider based on `ExternalLocaleProvider`. Do not mount another root `@orderly.network/i18n` `LocaleProvider` inside the package.
|
|
130
|
+
|
|
131
|
+
For host apps, bundling SDK locales with your `extend` JSON via `LocaleProvider` + `resources` is still the recommended setup when you own the provider tree. See [Async resources (Vite)](./examples.md#async-resources-vite), [Async resources (Next.js and webpack)](./examples.md#async-resources-nextjs-and-webpack), and [Sync resources](./examples.md#sync-resources).
|
|
127
132
|
|
|
128
133
|
### `ExternalLocaleProvider`
|
|
129
134
|
|
|
130
135
|
- **Async:** `(lang, ns) => Promise<Record<string, string>>` — invoked when the locale changes (same `ns` behavior as above when used through `registerResources`).
|
|
131
136
|
- **Sync:** static `Resources` map; all listed locales are registered on mount.
|
|
132
137
|
|
|
133
|
-
Async
|
|
138
|
+
Async external resources are also registered as preloaders while their provider is mounted. Calls to the package singleton `i18n.changeLanguage(locale)` wait for those mounted external resources to load the target locale before the language is switched. This keeps plugin/host extension bundles lazy by locale while ensuring the first render after the language switch already has the target external messages registered.
|
|
139
|
+
|
|
140
|
+
#### Async example (recommended for external packages)
|
|
141
|
+
|
|
142
|
+
For external SDK packages or plugin packages, ship a provider like
|
|
143
|
+
`package-template/src/i18n/provider.tsx`: preload the default English messages,
|
|
144
|
+
load non-English JSON chunks lazily with statically analyzable imports, and wrap
|
|
145
|
+
the package subtree with `ExternalLocaleProvider`.
|
|
146
|
+
|
|
147
|
+
This keeps the host app in charge of the root `LocaleProvider` while your package contributes its own translation resources to the shared singleton `i18n` instance. Use explicit per-locale dynamic imports so webpack/Next can resolve locale JSON chunks reliably. Vite accepts the same pattern.
|
|
134
148
|
|
|
135
149
|
```tsx
|
|
150
|
+
import { FC, PropsWithChildren } from "react";
|
|
136
151
|
import {
|
|
137
152
|
AsyncResources,
|
|
138
153
|
ExternalLocaleProvider,
|
|
154
|
+
importLocaleJsonModule,
|
|
139
155
|
LocaleCode,
|
|
140
|
-
|
|
156
|
+
LocaleEnum,
|
|
157
|
+
preloadDefaultResource,
|
|
158
|
+
type LocaleJsonModule,
|
|
141
159
|
} from "@orderly.network/i18n";
|
|
160
|
+
import { LocaleMessages } from "./module";
|
|
161
|
+
|
|
162
|
+
type LocaleJsonLoader = () => Promise<LocaleJsonModule>;
|
|
163
|
+
|
|
164
|
+
const localeJsonLoaders: Record<LocaleEnum, LocaleJsonLoader | undefined> = {
|
|
165
|
+
[LocaleEnum.en]: undefined,
|
|
166
|
+
[LocaleEnum.zh]: () => import("./locales/zh.json"),
|
|
167
|
+
[LocaleEnum.ja]: () => import("./locales/ja.json"),
|
|
168
|
+
[LocaleEnum.es]: () => import("./locales/es.json"),
|
|
169
|
+
[LocaleEnum.ko]: () => import("./locales/ko.json"),
|
|
170
|
+
[LocaleEnum.vi]: () => import("./locales/vi.json"),
|
|
171
|
+
[LocaleEnum.de]: () => import("./locales/de.json"),
|
|
172
|
+
[LocaleEnum.fr]: () => import("./locales/fr.json"),
|
|
173
|
+
[LocaleEnum.ru]: () => import("./locales/ru.json"),
|
|
174
|
+
[LocaleEnum.id]: () => import("./locales/id.json"),
|
|
175
|
+
[LocaleEnum.tr]: () => import("./locales/tr.json"),
|
|
176
|
+
[LocaleEnum.it]: () => import("./locales/it.json"),
|
|
177
|
+
[LocaleEnum.pt]: () => import("./locales/pt.json"),
|
|
178
|
+
[LocaleEnum.uk]: () => import("./locales/uk.json"),
|
|
179
|
+
[LocaleEnum.pl]: () => import("./locales/pl.json"),
|
|
180
|
+
[LocaleEnum.nl]: () => import("./locales/nl.json"),
|
|
181
|
+
[LocaleEnum.tc]: () => import("./locales/tc.json"),
|
|
182
|
+
};
|
|
142
183
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
184
|
+
// Seed fallback messages before async locale chunks load to avoid flashing i18n keys.
|
|
185
|
+
preloadDefaultResource(LocaleMessages);
|
|
186
|
+
|
|
187
|
+
const resources: AsyncResources = (lang: LocaleCode, _ns: string) => {
|
|
188
|
+
if (lang === LocaleEnum.en) {
|
|
189
|
+
return Promise.resolve(LocaleMessages);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const loader = localeJsonLoaders[lang as LocaleEnum];
|
|
193
|
+
return importLocaleJsonModule(loader);
|
|
147
194
|
};
|
|
148
195
|
|
|
149
|
-
export
|
|
196
|
+
export const LocaleProvider: FC<PropsWithChildren> = (props) => {
|
|
150
197
|
return (
|
|
151
|
-
<
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
</ExternalLocaleProvider>
|
|
155
|
-
</LocaleProvider>
|
|
198
|
+
<ExternalLocaleProvider resources={resources}>
|
|
199
|
+
{props.children}
|
|
200
|
+
</ExternalLocaleProvider>
|
|
156
201
|
);
|
|
157
|
-
}
|
|
202
|
+
};
|
|
158
203
|
```
|
|
159
204
|
|
|
205
|
+
The exported `LocaleProvider` above is your package-local provider. It is not the root `LocaleProvider` from `@orderly.network/i18n`; rename it if your package needs to expose both.
|
|
206
|
+
|
|
207
|
+
`LocaleMessages` should be the package's English/default message map, and `./locales/<locale>.json` should contain the translated package messages for that locale. If your package supports only a subset of languages, keep the full `Record<LocaleEnum, ...>` shape but leave unsupported loaders as `undefined`; `importLocaleJsonModule(undefined)` safely returns an empty resource object.
|
|
208
|
+
|
|
160
209
|
Sync example:
|
|
161
210
|
|
|
162
211
|
```tsx
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orderly.network/i18n",
|
|
3
|
-
"version": "3.0.4-alpha.
|
|
3
|
+
"version": "3.0.4-alpha.4",
|
|
4
4
|
"description": "Internationalization for orderly sdk",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"react-dom": "^18.2.0",
|
|
51
51
|
"tsup": "^8.5.1",
|
|
52
52
|
"typescript": "^5.1.6",
|
|
53
|
-
"tsconfig": "1.0.4-alpha.
|
|
53
|
+
"tsconfig": "1.0.4-alpha.4"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"react": ">=18",
|