inline-i18n-multi-next 0.5.0 → 0.7.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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # inline-i18n-multi-next
4
4
 
5
- Next.js App Router integration for inline-i18n-multi. Full SSR/SSG support with SEO utilities.
5
+ Next.js App Router integration for inline-i18n-multi. Full SSR/SSG support with SEO utilities, rich text, locale detection, and i18n middleware.
6
6
 
7
7
  ## Installation
8
8
 
@@ -10,6 +10,13 @@ Next.js App Router integration for inline-i18n-multi. Full SSR/SSG support with
10
10
  npm install inline-i18n-multi-next
11
11
  ```
12
12
 
13
+ ## Entry Points
14
+
15
+ | Entry point | Environment | Key exports |
16
+ |---|---|---|
17
+ | `inline-i18n-multi-next/server` | Server Components | `it`, `t`, `configureI18n`, `generateLocaleParams`, `createMetadata`, `getAlternates`, `createI18nMiddleware` |
18
+ | `inline-i18n-multi-next/client` | Client Components | `LocaleProvider`, `useLocale`, `useT`, `it`, `T`, `RichText`, `useRichText`, `useLoadDictionaries`, `useDetectedLocale`, `registerFormatter`, `clearFormatters`, `detectLocale`, `clearICUCache`, `restoreLocale`, `configure`, `resetConfig` |
19
+
13
20
  ## Quick Start
14
21
 
15
22
  ### Layout Setup
@@ -88,6 +95,122 @@ export function ClientComponent() {
88
95
  }
89
96
  ```
90
97
 
98
+ ## Rich Text (Client Components)
99
+
100
+ Use `RichText` or `useRichText` to embed React components inside translated strings. Tags like `<link>text</link>` are mapped to component renderers.
101
+
102
+ ### RichText Component
103
+
104
+ ```tsx
105
+ 'use client'
106
+ import { RichText } from 'inline-i18n-multi-next/client'
107
+
108
+ export function TermsNotice() {
109
+ return (
110
+ <RichText
111
+ translations={{
112
+ en: 'Read <link>terms</link> and <bold>agree</bold>',
113
+ ko: '<link>약관</link>을 읽고 <bold>동의</bold>해주세요',
114
+ }}
115
+ components={{
116
+ link: (text) => <a href="/terms">{text}</a>,
117
+ bold: (text) => <strong>{text}</strong>,
118
+ }}
119
+ />
120
+ )
121
+ }
122
+ ```
123
+
124
+ ### useRichText Hook
125
+
126
+ ```tsx
127
+ 'use client'
128
+ import { useRichText } from 'inline-i18n-multi-next/client'
129
+
130
+ export function RichContent() {
131
+ const richT = useRichText({
132
+ link: (text) => <a href="/terms">{text}</a>,
133
+ bold: (text) => <strong>{text}</strong>,
134
+ })
135
+
136
+ return <p>{richT({ en: 'Click <link>here</link>', ko: '<link>여기</link> 클릭' })}</p>
137
+ }
138
+ ```
139
+
140
+ ## Lazy Loading (Client Components)
141
+
142
+ Use `useLoadDictionaries` to load translations on demand in client components.
143
+
144
+ ```tsx
145
+ 'use client'
146
+ import { useLoadDictionaries, useT } from 'inline-i18n-multi-next/client'
147
+ import { useLocale } from 'inline-i18n-multi-next/client'
148
+
149
+ export function LazySection() {
150
+ const locale = useLocale()
151
+ const { isLoading, error } = useLoadDictionaries(locale, 'dashboard')
152
+ const t = useT()
153
+
154
+ if (isLoading) return <p>Loading...</p>
155
+ if (error) return <p>Failed to load translations</p>
156
+
157
+ return <h2>{t('dashboard.title')}</h2>
158
+ }
159
+ ```
160
+
161
+ ## Locale Detection
162
+
163
+ ### Client-Side: useDetectedLocale
164
+
165
+ Automatically detect and set the user's locale from browser signals (navigator, cookie, URL).
166
+
167
+ ```tsx
168
+ 'use client'
169
+ import { useDetectedLocale } from 'inline-i18n-multi-next/client'
170
+
171
+ export function LocaleDetector() {
172
+ useDetectedLocale({
173
+ supportedLocales: ['en', 'ko', 'ja'],
174
+ defaultLocale: 'en',
175
+ sources: ['cookie', 'navigator'],
176
+ cookieName: 'NEXT_LOCALE',
177
+ })
178
+
179
+ return null // detection runs on mount, updates context automatically
180
+ }
181
+ ```
182
+
183
+ Detection sources (checked in order):
184
+
185
+ | Source | Description |
186
+ |---|---|
187
+ | `'navigator'` | Browser `navigator.languages` |
188
+ | `'cookie'` | Read from `document.cookie` |
189
+ | `'url'` | First path segment (e.g., `/ko/about`) |
190
+ | `'header'` | `Accept-Language` header (SSR) |
191
+
192
+ ### Server-Side: createI18nMiddleware
193
+
194
+ Redirect users to locale-prefixed routes based on cookies or `Accept-Language` header.
195
+
196
+ ```ts
197
+ // middleware.ts
198
+ import { createI18nMiddleware } from 'inline-i18n-multi-next/server'
199
+
200
+ export default createI18nMiddleware({
201
+ locales: ['en', 'ko', 'ja'],
202
+ defaultLocale: 'en',
203
+ localeDetection: true, // detect from Accept-Language (default: true)
204
+ cookieName: 'NEXT_LOCALE', // cookie for user preference (default: 'NEXT_LOCALE')
205
+ })
206
+
207
+ export const config = {
208
+ matcher: ['/((?!api|_next|.*\\..*).*)'],
209
+ }
210
+ ```
211
+
212
+ The middleware checks in order: URL locale prefix, cookie preference, then `Accept-Language` header. If no locale prefix is found, it redirects to the detected locale path.
213
+
91
214
  ## SEO Utilities
92
215
 
93
216
  ```tsx
@@ -106,6 +229,56 @@ export async function generateMetadata({ params }) {
106
229
  }
107
230
  ```
108
231
 
232
+ ## Plural Shorthand (v0.7.0)
233
+
234
+ Concise plural syntax:
235
+
236
+ ```tsx
237
+ // Server Component
238
+ export default async function Page() {
239
+ return (
240
+ <p>
241
+ {await it({
242
+ en: '{count, p, item|items}',
243
+ ko: '{count}개',
244
+ }, { count: 5 })}
245
+ </p>
246
+ )
247
+ }
248
+
249
+ // Client Component - also supports 3-part (zero|singular|plural)
250
+ <T en="{count, p, no items|item|items}" ko="{count, p, 없음|개|개}" count={0} />
251
+ ```
252
+
253
+ ## Locale Persistence (v0.7.0)
254
+
255
+ Auto-save and restore locale:
256
+
257
+ ```tsx
258
+ 'use client'
259
+ import { configure, restoreLocale } from 'inline-i18n-multi-next/client'
260
+
261
+ configure({
262
+ persistLocale: { storage: 'cookie', key: 'LOCALE', expires: 365 }
263
+ })
264
+
265
+ // Restore on app init
266
+ const saved = restoreLocale() // returns locale string or undefined
267
+ ```
268
+
269
+ ## Custom Formatters
270
+
271
+ Register custom ICU formatters via the core re-exports.
272
+
273
+ ```tsx
274
+ 'use client'
275
+ import { registerFormatter, clearFormatters } from 'inline-i18n-multi-next/client'
276
+
277
+ registerFormatter('uppercase', (value) => String(value).toUpperCase())
278
+
279
+ // Use in translations: {name, uppercase}
280
+ ```
281
+
109
282
  ## Documentation
110
283
 
111
284
  **Please read the [full documentation on GitHub](https://github.com/exiivy98/inline-i18n-multi)** for complete API reference, SEO best practices, and advanced patterns.
package/dist/client.d.mts CHANGED
@@ -1 +1 @@
1
- export { Dictionaries, Dictionary, Locale, LocaleProvider, PluralRules, RichText, RichTextSegment, T, TranslationVars, Translations, clearDictionaries, en_de, en_es, en_fr, en_ja, en_zh, getDictionary, getLoadedLocales, getLocale, hasTranslation, isLoaded, it, it_de, it_es, it_fr, it_ja, it_zh, ja_es, ja_zh, loadAsync, loadDictionaries, loadDictionary, parseRichText, setLocale, t, useLoadDictionaries, useLocale, useRichText, useT, zh_es } from 'inline-i18n-multi-react';
1
+ export { CustomFormatter, DetectLocaleOptions, DetectSource, Dictionaries, Dictionary, Locale, LocaleProvider, PluralRules, RichText, RichTextSegment, T, TranslationVars, Translations, clearDictionaries, clearFormatters, clearICUCache, detectLocale, en_de, en_es, en_fr, en_ja, en_zh, getDictionary, getLoadedLocales, getLocale, hasTranslation, isLoaded, it, it_de, it_es, it_fr, it_ja, it_zh, ja_es, ja_zh, loadAsync, loadDictionaries, loadDictionary, parseRichText, registerFormatter, restoreLocale, setLocale, t, useDetectedLocale, useLoadDictionaries, useLocale, useRichText, useT, zh_es } from 'inline-i18n-multi-react';
package/dist/client.d.ts CHANGED
@@ -1 +1 @@
1
- export { Dictionaries, Dictionary, Locale, LocaleProvider, PluralRules, RichText, RichTextSegment, T, TranslationVars, Translations, clearDictionaries, en_de, en_es, en_fr, en_ja, en_zh, getDictionary, getLoadedLocales, getLocale, hasTranslation, isLoaded, it, it_de, it_es, it_fr, it_ja, it_zh, ja_es, ja_zh, loadAsync, loadDictionaries, loadDictionary, parseRichText, setLocale, t, useLoadDictionaries, useLocale, useRichText, useT, zh_es } from 'inline-i18n-multi-react';
1
+ export { CustomFormatter, DetectLocaleOptions, DetectSource, Dictionaries, Dictionary, Locale, LocaleProvider, PluralRules, RichText, RichTextSegment, T, TranslationVars, Translations, clearDictionaries, clearFormatters, clearICUCache, detectLocale, en_de, en_es, en_fr, en_ja, en_zh, getDictionary, getLoadedLocales, getLocale, hasTranslation, isLoaded, it, it_de, it_es, it_fr, it_ja, it_zh, ja_es, ja_zh, loadAsync, loadDictionaries, loadDictionary, parseRichText, registerFormatter, restoreLocale, setLocale, t, useDetectedLocale, useLoadDictionaries, useLocale, useRichText, useT, zh_es } from 'inline-i18n-multi-react';
package/dist/client.js CHANGED
@@ -20,6 +20,18 @@ Object.defineProperty(exports, "clearDictionaries", {
20
20
  enumerable: true,
21
21
  get: function () { return inlineI18nMultiReact.clearDictionaries; }
22
22
  });
23
+ Object.defineProperty(exports, "clearFormatters", {
24
+ enumerable: true,
25
+ get: function () { return inlineI18nMultiReact.clearFormatters; }
26
+ });
27
+ Object.defineProperty(exports, "clearICUCache", {
28
+ enumerable: true,
29
+ get: function () { return inlineI18nMultiReact.clearICUCache; }
30
+ });
31
+ Object.defineProperty(exports, "detectLocale", {
32
+ enumerable: true,
33
+ get: function () { return inlineI18nMultiReact.detectLocale; }
34
+ });
23
35
  Object.defineProperty(exports, "en_de", {
24
36
  enumerable: true,
25
37
  get: function () { return inlineI18nMultiReact.en_de; }
@@ -108,6 +120,14 @@ Object.defineProperty(exports, "parseRichText", {
108
120
  enumerable: true,
109
121
  get: function () { return inlineI18nMultiReact.parseRichText; }
110
122
  });
123
+ Object.defineProperty(exports, "registerFormatter", {
124
+ enumerable: true,
125
+ get: function () { return inlineI18nMultiReact.registerFormatter; }
126
+ });
127
+ Object.defineProperty(exports, "restoreLocale", {
128
+ enumerable: true,
129
+ get: function () { return inlineI18nMultiReact.restoreLocale; }
130
+ });
111
131
  Object.defineProperty(exports, "setLocale", {
112
132
  enumerable: true,
113
133
  get: function () { return inlineI18nMultiReact.setLocale; }
@@ -116,6 +136,10 @@ Object.defineProperty(exports, "t", {
116
136
  enumerable: true,
117
137
  get: function () { return inlineI18nMultiReact.t; }
118
138
  });
139
+ Object.defineProperty(exports, "useDetectedLocale", {
140
+ enumerable: true,
141
+ get: function () { return inlineI18nMultiReact.useDetectedLocale; }
142
+ });
119
143
  Object.defineProperty(exports, "useLoadDictionaries", {
120
144
  enumerable: true,
121
145
  get: function () { return inlineI18nMultiReact.useLoadDictionaries; }
package/dist/client.mjs CHANGED
@@ -1,3 +1,3 @@
1
- export { LocaleProvider, RichText, T, clearDictionaries, en_de, en_es, en_fr, en_ja, en_zh, getDictionary, getLoadedLocales, getLocale, hasTranslation, isLoaded, it, it_de, it_es, it_fr, it_ja, it_zh, ja_es, ja_zh, loadAsync, loadDictionaries, loadDictionary, parseRichText, setLocale, t, useLoadDictionaries, useLocale, useRichText, useT, zh_es } from 'inline-i18n-multi-react';
1
+ export { LocaleProvider, RichText, T, clearDictionaries, clearFormatters, clearICUCache, detectLocale, en_de, en_es, en_fr, en_ja, en_zh, getDictionary, getLoadedLocales, getLocale, hasTranslation, isLoaded, it, it_de, it_es, it_fr, it_ja, it_zh, ja_es, ja_zh, loadAsync, loadDictionaries, loadDictionary, parseRichText, registerFormatter, restoreLocale, setLocale, t, useDetectedLocale, useLoadDictionaries, useLocale, useRichText, useT, zh_es } from 'inline-i18n-multi-react';
2
2
  //# sourceMappingURL=client.mjs.map
3
3
  //# sourceMappingURL=client.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inline-i18n-multi-next",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Next.js integration for inline-i18n-multi",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -51,8 +51,8 @@
51
51
  "react": "^18.0.0 || ^19.0.0"
52
52
  },
53
53
  "dependencies": {
54
- "inline-i18n-multi": "0.5.0",
55
- "inline-i18n-multi-react": "0.5.0"
54
+ "inline-i18n-multi": "0.7.0",
55
+ "inline-i18n-multi-react": "0.7.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/react": "^19.0.2",