inline-i18n-multi 0.1.1 → 0.1.3
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 +280 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,53 +1,314 @@
|
|
|
1
1
|
# inline-i18n-multi
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/inline-i18n-multi)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
**Write translations inline. Find them instantly.**
|
|
7
|
+
|
|
8
|
+
> For complete documentation, examples, and best practices, please read the [full documentation on GitHub](https://github.com/exiivy98/inline-i18n-multi).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## The Problem
|
|
13
|
+
|
|
14
|
+
Traditional i18n libraries separate translations from code:
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
// Component.tsx
|
|
18
|
+
<p>{t('greeting.hello')}</p>
|
|
19
|
+
|
|
20
|
+
// en.json
|
|
21
|
+
{ "greeting": { "hello": "Hello" } }
|
|
22
|
+
|
|
23
|
+
// ko.json
|
|
24
|
+
{ "greeting": { "hello": "안녕하세요" } }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
When you see "Hello" in your app and want to find it in the code, you have to:
|
|
28
|
+
1. Search for "Hello" in JSON files
|
|
29
|
+
2. Find the key `greeting.hello`
|
|
30
|
+
3. Search for that key in your code
|
|
31
|
+
4. Finally find `t('greeting.hello')`
|
|
32
|
+
|
|
33
|
+
**This is slow and frustrating.**
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## The Solution
|
|
38
|
+
|
|
39
|
+
With `inline-i18n-multi`, translations live in your code:
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<p>{it('안녕하세요', 'Hello')}</p>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
See "Hello" in your app? Just search for "Hello" in your codebase. **Done.**
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- **Inline translations** - Write translations right where you use them
|
|
52
|
+
- **Instant search** - Find any text in your codebase immediately
|
|
53
|
+
- **Type-safe** - Full TypeScript support with variable type checking
|
|
54
|
+
- **Multiple languages** - Support for any number of locales
|
|
55
|
+
- **i18n compatible** - Support for traditional key-based translations with JSON dictionaries
|
|
56
|
+
- **Plural support** - Built-in plural forms using `Intl.PluralRules`
|
|
57
|
+
- **Variable interpolation** - `{name}` syntax for dynamic values
|
|
58
|
+
|
|
59
|
+
---
|
|
4
60
|
|
|
5
61
|
## Installation
|
|
6
62
|
|
|
7
63
|
```bash
|
|
64
|
+
# npm
|
|
8
65
|
npm install inline-i18n-multi
|
|
66
|
+
|
|
67
|
+
# yarn
|
|
68
|
+
yarn add inline-i18n-multi
|
|
69
|
+
|
|
70
|
+
# pnpm
|
|
71
|
+
pnpm add inline-i18n-multi
|
|
9
72
|
```
|
|
10
73
|
|
|
74
|
+
---
|
|
75
|
+
|
|
11
76
|
## Quick Start
|
|
12
77
|
|
|
13
|
-
```
|
|
78
|
+
```typescript
|
|
14
79
|
import { it, setLocale } from 'inline-i18n-multi'
|
|
15
80
|
|
|
16
|
-
|
|
81
|
+
// Set current locale
|
|
82
|
+
setLocale('en')
|
|
17
83
|
|
|
18
|
-
//
|
|
19
|
-
it('안녕하세요', 'Hello') // →
|
|
84
|
+
// Shorthand syntax (Korean + English)
|
|
85
|
+
it('안녕하세요', 'Hello') // → "Hello"
|
|
20
86
|
|
|
21
|
-
// Object syntax
|
|
22
|
-
it({ ko: '
|
|
87
|
+
// Object syntax (multiple languages)
|
|
88
|
+
it({ ko: '안녕하세요', en: 'Hello', ja: 'こんにちは' }) // → "Hello"
|
|
23
89
|
|
|
24
90
|
// With variables
|
|
25
|
-
it('안녕, {name}님', 'Hello, {name}', { name: '
|
|
91
|
+
it('안녕, {name}님', 'Hello, {name}', { name: 'John' }) // → "Hello, John"
|
|
26
92
|
```
|
|
27
93
|
|
|
28
|
-
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Key-Based Translations (i18n Compatible)
|
|
97
|
+
|
|
98
|
+
For projects that already use JSON translation files, or when you need traditional key-based translations:
|
|
29
99
|
|
|
30
|
-
```
|
|
31
|
-
import { t, loadDictionaries
|
|
100
|
+
```typescript
|
|
101
|
+
import { t, loadDictionaries } from 'inline-i18n-multi'
|
|
32
102
|
|
|
103
|
+
// Load translation dictionaries
|
|
33
104
|
loadDictionaries({
|
|
34
|
-
en: {
|
|
35
|
-
|
|
105
|
+
en: {
|
|
106
|
+
greeting: { hello: 'Hello', goodbye: 'Goodbye' },
|
|
107
|
+
items: { count_one: '{count} item', count_other: '{count} items' },
|
|
108
|
+
welcome: 'Welcome, {name}!'
|
|
109
|
+
},
|
|
110
|
+
ko: {
|
|
111
|
+
greeting: { hello: '안녕하세요', goodbye: '안녕히 가세요' },
|
|
112
|
+
items: { count_other: '{count}개 항목' },
|
|
113
|
+
welcome: '환영합니다, {name}님!'
|
|
114
|
+
}
|
|
36
115
|
})
|
|
37
116
|
|
|
38
|
-
|
|
39
|
-
t('greeting') // →
|
|
40
|
-
|
|
117
|
+
// Basic key-based translation
|
|
118
|
+
t('greeting.hello') // → "Hello" (when locale is 'en')
|
|
119
|
+
|
|
120
|
+
// With variables
|
|
121
|
+
t('welcome', { name: 'John' }) // → "Welcome, John!"
|
|
122
|
+
|
|
123
|
+
// Plural support (uses Intl.PluralRules)
|
|
124
|
+
t('items.count', { count: 1 }) // → "1 item"
|
|
125
|
+
t('items.count', { count: 5 }) // → "5 items"
|
|
126
|
+
|
|
127
|
+
// Override locale
|
|
128
|
+
t('greeting.hello', undefined, 'ko') // → "안녕하세요"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Utility Functions
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
import { hasTranslation, getLoadedLocales, getDictionary } from 'inline-i18n-multi'
|
|
137
|
+
|
|
138
|
+
// Check if translation exists
|
|
139
|
+
hasTranslation('greeting.hello') // → true
|
|
140
|
+
hasTranslation('missing.key') // → false
|
|
141
|
+
|
|
142
|
+
// Get loaded locales
|
|
143
|
+
getLoadedLocales() // → ['en', 'ko']
|
|
144
|
+
|
|
145
|
+
// Get dictionary for a locale
|
|
146
|
+
getDictionary('en') // → { greeting: { hello: 'Hello', ... }, ... }
|
|
41
147
|
```
|
|
42
148
|
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Language Pair Helpers
|
|
152
|
+
|
|
153
|
+
For common language combinations, use the shorthand helpers:
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { it_ja, en_zh, ja_es } from 'inline-i18n-multi'
|
|
157
|
+
|
|
158
|
+
// Korean ↔ Japanese
|
|
159
|
+
it_ja('안녕하세요', 'こんにちは')
|
|
160
|
+
|
|
161
|
+
// English ↔ Chinese
|
|
162
|
+
en_zh('Hello', '你好')
|
|
163
|
+
|
|
164
|
+
// Japanese ↔ Spanish
|
|
165
|
+
ja_es('こんにちは', 'Hola')
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Available helpers:
|
|
169
|
+
- `it` (ko↔en), `it_ja`, `it_zh`, `it_es`, `it_fr`, `it_de`
|
|
170
|
+
- `en_ja`, `en_zh`, `en_es`, `en_fr`, `en_de`
|
|
171
|
+
- `ja_zh`, `ja_es`, `zh_es`
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## API Reference
|
|
176
|
+
|
|
177
|
+
### Core Functions
|
|
178
|
+
|
|
179
|
+
| Function | Description |
|
|
180
|
+
|----------|-------------|
|
|
181
|
+
| `it(ko, en, vars?)` | Translate with Korean and English |
|
|
182
|
+
| `it(translations, vars?)` | Translate with object syntax |
|
|
183
|
+
| `setLocale(locale)` | Set current locale |
|
|
184
|
+
| `getLocale()` | Get current locale |
|
|
185
|
+
|
|
186
|
+
### Key-Based Translation
|
|
187
|
+
|
|
188
|
+
| Function | Description |
|
|
189
|
+
|----------|-------------|
|
|
190
|
+
| `t(key, vars?, locale?)` | Key-based translation with optional locale override |
|
|
191
|
+
| `loadDictionaries(dicts)` | Load translation dictionaries for multiple locales |
|
|
192
|
+
| `loadDictionary(locale, dict)` | Load dictionary for a single locale |
|
|
193
|
+
| `hasTranslation(key, locale?)` | Check if translation key exists |
|
|
194
|
+
| `getLoadedLocales()` | Get array of loaded locale codes |
|
|
195
|
+
| `getDictionary(locale)` | Get dictionary for a specific locale |
|
|
196
|
+
|
|
197
|
+
### Types
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
type Locale = string
|
|
201
|
+
type Translations = Record<Locale, string>
|
|
202
|
+
type TranslationVars = Record<string, string | number>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Why Inline Translations?
|
|
208
|
+
|
|
209
|
+
### Traditional i18n
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
Code → Key → JSON file → Translation
|
|
213
|
+
↑
|
|
214
|
+
Hard to trace
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Inline i18n
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
Code ← Translation (same place!)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
| Aspect | Traditional | Inline |
|
|
224
|
+
|--------|-------------|--------|
|
|
225
|
+
| Finding text in code | Hard (key lookup) | Easy (direct search) |
|
|
226
|
+
| Adding translations | Create key, add to JSON | Write inline |
|
|
227
|
+
| Refactoring | Update key references | Automatic |
|
|
228
|
+
| Code review | Check JSON separately | All visible in diff |
|
|
229
|
+
| Type safety | Limited | Full support |
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
43
233
|
## Framework Integrations
|
|
44
234
|
|
|
45
|
-
|
|
46
|
-
|
|
235
|
+
### React
|
|
236
|
+
|
|
237
|
+
React hooks and components for inline translations. Includes `LocaleProvider` for context management, `useLocale()` hook for locale state, and `T` component for JSX translations. Automatic cookie persistence when locale changes.
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
npm install inline-i18n-multi-react
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
[View React package →](https://www.npmjs.com/package/inline-i18n-multi-react)
|
|
244
|
+
|
|
245
|
+
### Next.js
|
|
246
|
+
|
|
247
|
+
Full Next.js App Router integration with SSR/SSG support. Server Components use async `it()`, Client Components use React bindings. Includes SEO utilities: `createMetadata()` for dynamic metadata, `getAlternates()` for hreflang links, and `createI18nMiddleware()` for locale detection.
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
npm install inline-i18n-multi-next
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
[View Next.js package →](https://www.npmjs.com/package/inline-i18n-multi-next)
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Build-Time Optimization
|
|
258
|
+
|
|
259
|
+
### Babel Plugin
|
|
260
|
+
|
|
261
|
+
Transform `it()` calls at build time for better performance. Extracts translations for static analysis and enables dead code elimination for unused locales.
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
npm install -D @inline-i18n-multi/babel-plugin
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
[View Babel plugin →](https://www.npmjs.com/package/@inline-i18n-multi/babel-plugin)
|
|
268
|
+
|
|
269
|
+
### SWC Plugin
|
|
270
|
+
|
|
271
|
+
SWC plugin for Next.js 13+ projects. Faster than Babel with the same optimization benefits. Configure in `next.config.js` under `experimental.swcPlugins`.
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
npm install -D @inline-i18n-multi/swc-plugin
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
[View SWC plugin →](https://www.npmjs.com/package/@inline-i18n-multi/swc-plugin)
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Developer Tools
|
|
282
|
+
|
|
283
|
+
### CLI
|
|
284
|
+
|
|
285
|
+
Command-line tools for translation management. Find translations with `inline-i18n find "text"`, validate consistency with `inline-i18n validate`, and generate coverage reports with `inline-i18n coverage`.
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
npm install -D @inline-i18n-multi/cli
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
[View CLI package →](https://www.npmjs.com/package/@inline-i18n-multi/cli)
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Requirements
|
|
296
|
+
|
|
297
|
+
- Node.js 18+
|
|
298
|
+
- TypeScript 5.0+ (recommended)
|
|
299
|
+
|
|
300
|
+
---
|
|
47
301
|
|
|
48
302
|
## Documentation
|
|
49
303
|
|
|
50
|
-
|
|
304
|
+
**Please read the [full documentation on GitHub](https://github.com/exiivy98/inline-i18n-multi)** for:
|
|
305
|
+
- Complete API reference
|
|
306
|
+
- Framework integrations (React, Next.js)
|
|
307
|
+
- Build-time optimization
|
|
308
|
+
- CLI tools
|
|
309
|
+
- Best practices and examples
|
|
310
|
+
|
|
311
|
+
---
|
|
51
312
|
|
|
52
313
|
## License
|
|
53
314
|
|