@translation-cms/sync 1.2.10 → 1.2.12

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.
Files changed (116) hide show
  1. package/README.md +301 -156
  2. package/dist/api.d.ts +79 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +151 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/bin.js +51 -17
  7. package/dist/bin.js.map +1 -1
  8. package/dist/commands/init.d.ts +8 -0
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js +18 -0
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/pull.d.ts +7 -0
  13. package/dist/commands/pull.d.ts.map +1 -1
  14. package/dist/commands/pull.js +15 -2
  15. package/dist/commands/pull.js.map +1 -1
  16. package/dist/commands/status.d.ts +12 -0
  17. package/dist/commands/status.d.ts.map +1 -1
  18. package/dist/commands/status.js +16 -0
  19. package/dist/commands/status.js.map +1 -1
  20. package/dist/commands/sync.d.ts +10 -0
  21. package/dist/commands/sync.d.ts.map +1 -1
  22. package/dist/commands/sync.js +19 -3
  23. package/dist/commands/sync.js.map +1 -1
  24. package/dist/commands/watch.d.ts +14 -0
  25. package/dist/commands/watch.d.ts.map +1 -1
  26. package/dist/commands/watch.js +23 -3
  27. package/dist/commands/watch.js.map +1 -1
  28. package/dist/config/config-internals/args.d.ts +11 -0
  29. package/dist/config/config-internals/args.d.ts.map +1 -0
  30. package/dist/config/config-internals/args.js +22 -0
  31. package/dist/config/config-internals/args.js.map +1 -0
  32. package/dist/config/config-internals/env.d.ts +10 -0
  33. package/dist/config/config-internals/env.d.ts.map +1 -0
  34. package/dist/config/config-internals/env.js +35 -0
  35. package/dist/config/config-internals/env.js.map +1 -0
  36. package/dist/config/config-internals/file.d.ts +11 -0
  37. package/dist/config/config-internals/file.d.ts.map +1 -0
  38. package/dist/config/config-internals/file.js +28 -0
  39. package/dist/config/config-internals/file.js.map +1 -0
  40. package/dist/config/config-internals/resolve.d.ts +21 -0
  41. package/dist/config/config-internals/resolve.d.ts.map +1 -0
  42. package/dist/config/config-internals/resolve.js +73 -0
  43. package/dist/config/config-internals/resolve.js.map +1 -0
  44. package/dist/config/config-internals/root.d.ts +9 -0
  45. package/dist/config/config-internals/root.d.ts.map +1 -0
  46. package/dist/config/config-internals/root.js +22 -0
  47. package/dist/config/config-internals/root.js.map +1 -0
  48. package/dist/config/config-internals/types.d.ts +83 -0
  49. package/dist/config/config-internals/types.d.ts.map +1 -0
  50. package/dist/config/config-internals/types.js +9 -0
  51. package/dist/config/config-internals/types.js.map +1 -0
  52. package/dist/config/resolve-config.d.ts +9 -90
  53. package/dist/config/resolve-config.d.ts.map +1 -1
  54. package/dist/config/resolve-config.js +7 -123
  55. package/dist/config/resolve-config.js.map +1 -1
  56. package/dist/core/api-internals/pull.d.ts +9 -1
  57. package/dist/core/api-internals/pull.d.ts.map +1 -1
  58. package/dist/core/api-internals/pull.js +41 -28
  59. package/dist/core/api-internals/pull.js.map +1 -1
  60. package/dist/core/api-internals/sync.d.ts +9 -2
  61. package/dist/core/api-internals/sync.d.ts.map +1 -1
  62. package/dist/core/api-internals/sync.js +18 -2
  63. package/dist/core/api-internals/sync.js.map +1 -1
  64. package/dist/core/cache-internals/format.d.ts +16 -0
  65. package/dist/core/cache-internals/format.d.ts.map +1 -1
  66. package/dist/core/cache-internals/format.js +17 -0
  67. package/dist/core/cache-internals/format.js.map +1 -1
  68. package/dist/core/cache-internals/params.d.ts.map +1 -1
  69. package/dist/core/cache-internals/params.js +24 -24
  70. package/dist/core/cache-internals/params.js.map +1 -1
  71. package/dist/core/cache-internals/pull.d.ts +12 -0
  72. package/dist/core/cache-internals/pull.d.ts.map +1 -1
  73. package/dist/core/cache-internals/pull.js +13 -0
  74. package/dist/core/cache-internals/pull.js.map +1 -1
  75. package/dist/core/cache-internals/sync.d.ts +23 -0
  76. package/dist/core/cache-internals/sync.d.ts.map +1 -1
  77. package/dist/core/cache-internals/sync.js +33 -0
  78. package/dist/core/cache-internals/sync.js.map +1 -1
  79. package/dist/core/cache-internals/types.d.ts +20 -0
  80. package/dist/core/cache-internals/types.d.ts.map +1 -1
  81. package/dist/core/scanner-internals/ast.d.ts +23 -5
  82. package/dist/core/scanner-internals/ast.d.ts.map +1 -1
  83. package/dist/core/scanner-internals/ast.js +25 -5
  84. package/dist/core/scanner-internals/ast.js.map +1 -1
  85. package/dist/core/scanner-internals/file-walker.d.ts +3 -2
  86. package/dist/core/scanner-internals/file-walker.d.ts.map +1 -1
  87. package/dist/core/scanner-internals/file-walker.js +10 -12
  88. package/dist/core/scanner-internals/file-walker.js.map +1 -1
  89. package/dist/core/scanner-internals/import-resolver.d.ts +9 -1
  90. package/dist/core/scanner-internals/import-resolver.d.ts.map +1 -1
  91. package/dist/core/scanner-internals/import-resolver.js +58 -63
  92. package/dist/core/scanner-internals/import-resolver.js.map +1 -1
  93. package/dist/core/scanner-internals/key-extractor.d.ts +12 -8
  94. package/dist/core/scanner-internals/key-extractor.d.ts.map +1 -1
  95. package/dist/core/scanner-internals/key-extractor.js +125 -97
  96. package/dist/core/scanner-internals/key-extractor.js.map +1 -1
  97. package/dist/core/scanner-internals/route-detector.d.ts +16 -8
  98. package/dist/core/scanner-internals/route-detector.d.ts.map +1 -1
  99. package/dist/core/scanner-internals/route-detector.js +37 -33
  100. package/dist/core/scanner-internals/route-detector.js.map +1 -1
  101. package/dist/core/scanner.d.ts.map +1 -1
  102. package/dist/core/scanner.js +25 -8
  103. package/dist/core/scanner.js.map +1 -1
  104. package/dist/next.d.ts +28 -0
  105. package/dist/next.d.ts.map +1 -0
  106. package/dist/next.js +65 -0
  107. package/dist/next.js.map +1 -0
  108. package/dist/preview/internals/highlight.d.ts +16 -7
  109. package/dist/preview/internals/highlight.d.ts.map +1 -1
  110. package/dist/preview/internals/highlight.js +71 -60
  111. package/dist/preview/internals/highlight.js.map +1 -1
  112. package/dist/scaffold/intenrals/scaffold.d.ts +17 -0
  113. package/dist/scaffold/intenrals/scaffold.d.ts.map +1 -1
  114. package/dist/scaffold/intenrals/scaffold.js +19 -0
  115. package/dist/scaffold/intenrals/scaffold.js.map +1 -1
  116. package/package.json +16 -3
package/README.md CHANGED
@@ -1,18 +1,98 @@
1
1
  # @translation-cms/sync
2
2
 
3
- Automatisch vertaalsleutels uit je codebase scannen, syncen met de Translations
4
- CMS, en vertalingen ophalen als lokale JSON-bestanden. Gebouwd voor Next.js +
5
- i18next.
3
+ Automatically scan translation keys from your codebase, sync with the
4
+ Translations CMS, and fetch translations as local JSON files. Built for
5
+ Next.js + i18next.
6
6
 
7
- ## Wat is dit?
7
+ ## Integration Methods
8
8
 
9
- Een CLI-tool die je workflow vereenvoudigt:
9
+ Choose the approach that fits your workflow:
10
10
 
11
- - 🔍 **Scant** je code voor translation keys (React-i18next patroon)
12
- - 📤 **Synct** nieuwe keys naar de Translations CMS
13
- - 📥 **Haalt** vertalingen op als JSON-bestanden
14
- - 🎯 **Preview** functie waarin editors live kunnen zien hoe hun tekst in je app
15
- eruit ziet
11
+ - **Next.js Plugin** (Recommended) Automatic sync on `next dev` and
12
+ `next build`
13
+ - **CLI** (Manual) `pnpm sync-translations` for on-demand control
14
+ - **Programmatic API** Call sync/pull directly in your code or scripts
15
+
16
+ ### Method 1: Next.js Plugin (Automatic)
17
+
18
+ Edit `next.config.ts`:
19
+
20
+ ```ts
21
+ import withTranslationsCMS from '@translation-cms/sync/next';
22
+
23
+ export default withTranslationsCMS(
24
+ {
25
+ // your Next.js config
26
+ },
27
+ {
28
+ pullOnBuild: true, // auto pull on build
29
+ pullOnDev: true, // auto pull on dev startup
30
+ }
31
+ );
32
+ ```
33
+
34
+ Your translations sync automatically. That's it. No extra commands needed.
35
+
36
+ ### Method 2: CLI (Manual)
37
+
38
+ ```bash
39
+ # Scan code + upload to CMS
40
+ pnpm sync-translations sync
41
+
42
+ # Download translations
43
+ pnpm sync-translations pull
44
+
45
+ # Watch mode — auto-sync on file changes
46
+ pnpm sync-translations watch
47
+
48
+ # Interactive setup
49
+ pnpm sync-translations init
50
+ ```
51
+
52
+ ### Method 3: Programmatic API
53
+
54
+ Use in scripts, build tools, or CI/CD:
55
+
56
+ ```ts
57
+ import { syncTranslations, pullTranslations } from '@translation-cms/sync/api';
58
+
59
+ // Scan and upload keys
60
+ await syncTranslations({
61
+ projectRoot: './my-app',
62
+ verbose: true,
63
+ });
64
+
65
+ // Download translations
66
+ await pullTranslations({
67
+ projectRoot: './my-app',
68
+ environment: 'production',
69
+ });
70
+
71
+ // Sync and pull in one go
72
+ import { syncAndPull } from '@translation-cms/sync/api';
73
+ await syncAndPull({ projectRoot: './my-app' });
74
+ ```
75
+
76
+ ### Choose Your Method
77
+
78
+ | Method | When to Use | Setup Time |
79
+ | -------------------- | --------------------------------- | ---------- |
80
+ | **Next.js Plugin** | Team projects, automatic workflow | 5 min |
81
+ | **CLI** | Manual control, debugging, CI/CD | 10 min |
82
+ | **Programmatic API** | Custom workflows, scripts | 5 min |
83
+
84
+ **Recommended:** Start with the **Next.js Plugin** for automatic updates during
85
+ development, then add CLI or API commands as needed.
86
+
87
+ ## What is this?
88
+
89
+ Hybrid translation management system with three integration methods:
90
+
91
+ - **Scans** your code for translation keys (React-i18next pattern)
92
+ - **Syncs** new keys to the Translations CMS
93
+ - **Fetches** translations as JSON files
94
+ - **Automatic or manual** — choose what works for your team
95
+ - **Programmatic API** — bring your own CI/CD or tooling
16
96
 
17
97
  ```
18
98
  Your Code → scan → CMS → pull → JSON files → i18next → Your App
@@ -20,32 +100,87 @@ Your Code → scan → CMS → pull → JSON files → i18next → Your App
20
100
 
21
101
  ---
22
102
 
23
- # Setup Handleiding — Van Nul Tot Functie
103
+ ## Programmatic API Reference
104
+
105
+ Use these functions when you need fine-grained control or integration with
106
+ custom workflows. Perfect for CI/CD pipelines, build tools, or custom scripts.
107
+
108
+ ### `syncTranslations(options?)`
24
109
 
25
- ## Stap 1: Vereisten
110
+ Scans your codebase for translation keys and uploads them to the CMS.
26
111
 
27
- Controleer wat je nodig hebt:
112
+ ```ts
113
+ import { syncTranslations } from '@translation-cms/sync/api';
114
+
115
+ const result = await syncTranslations({
116
+ projectRoot: './apps/web', // auto-detect if omitted
117
+ dryRun: false, // preview without uploading
118
+ force: false, // ignore cache
119
+ reportPath: './sync-report.json', // optional report output
120
+ verbose: true, // detailed logging
121
+ });
122
+
123
+ console.log(`Added ${result.keysAdded} keys`);
124
+ ```
28
125
 
29
- - ✅ Next.js project (v14+)
30
- - ✅ pnpm (aanbevolen) of npm
31
- - ✅ Translations CMS account + project aangemaakt
32
- - ✅ CMS project credentials (URL, project ID, API key)
126
+ ### `pullTranslations(options?)`
33
127
 
34
- ## Stap 2: Installatie
128
+ Fetches translations from the CMS and writes them as JSON files.
129
+
130
+ ```ts
131
+ import { pullTranslations } from '@translation-cms/sync/api';
132
+
133
+ const result = await pullTranslations({
134
+ projectRoot: './apps/web', // auto-detect if omitted
135
+ outputDir: './src/i18n/locales', // custom output location
136
+ force: false, // ignore cache
137
+ ttl: 300000, // cache duration in ms
138
+ environment: 'production', // pull from specific env
139
+ verbose: true, // detailed logging
140
+ });
141
+ ```
142
+
143
+ ### `syncAndPull(options?)`
144
+
145
+ Convenience function: sync keys then pull translations in one call.
146
+
147
+ ```ts
148
+ import { syncAndPull } from '@translation-cms/sync/api';
149
+
150
+ const { synced, pulled } = await syncAndPull({
151
+ projectRoot: './apps/web',
152
+ verbose: true,
153
+ });
154
+ ```
155
+
156
+ ---
157
+
158
+ # Setup Guide — From Zero to Working
159
+
160
+ ## Step 1: Prerequisites
161
+
162
+ Check what you need:
163
+
164
+ - Next.js project (v14+)
165
+ - pnpm (recommended) or npm
166
+ - Translations CMS account + project created
167
+ - CMS project credentials (URL, project ID, API key)
168
+
169
+ ## Step 2: Installation
35
170
 
36
171
  ```bash
37
172
  pnpm add @translation-cms/sync
38
173
  ```
39
174
 
40
- Plus de peer dependencies:
175
+ Plus the peer dependencies:
41
176
 
42
177
  ```bash
43
178
  pnpm add i18next react-i18next i18next-resources-to-backend
44
179
  ```
45
180
 
46
- ## Stap 3: CMS Credentials Instellen
181
+ ## Step 3: Set Up CMS Credentials
47
182
 
48
- Maak `.env.local` aan in je project root:
183
+ Create `.env.local` in your project root:
49
184
 
50
185
  ```bash
51
186
  NEXT_PUBLIC_CMS_URL=https://cms.example.com
@@ -53,38 +188,37 @@ NEXT_PUBLIC_CMS_PROJECT_ID=your-project-id
53
188
  CMS_SYNC_API_KEY=your-jwt-api-key
54
189
  ```
55
190
 
56
- De `CMS_SYNC_API_KEY` is een **JWT token** (geen UUID meer). Je vindt deze in de CMS
57
- onder **Project Settings → Environments → jouw environment → API Key**. Als de
58
- key die daar staat er nog uitziet als een UUID, gebruik dan "Regenerate" om een
59
- JWT te genereren.
191
+ The `CMS_SYNC_API_KEY` is a **JWT token**. You can find it in the CMS under
192
+ **Project Settings → Environments → your environment → API Key**. If the key
193
+ there still looks like a UUID, use "Regenerate" to generate a JWT.
60
194
 
61
- > **Let op:** gebruik `CMS_SYNC_API_KEY` (zonder `NEXT_PUBLIC_`). Dit voorkomt
62
- > dat de JWT per ongeluk in de browser terechtkomt. De oude naam
63
- > `NEXT_PUBLIC_CMS_ANON_KEY` werkt nog als fallback, maar wordt afgeraden.
195
+ > **Note:** use `CMS_SYNC_API_KEY` (without `NEXT_PUBLIC_`). This prevents the
196
+ > JWT from accidentally ending up in the browser. The old name
197
+ > `NEXT_PUBLIC_CMS_ANON_KEY` still works as a fallback, but is discouraged.
64
198
 
65
- ## Stap 4: Automatische Setup (Aanbevolen)
199
+ ## Step 4: Automatic Setup (Recommended)
66
200
 
67
- Run de interactive setup wizard:
201
+ Run the interactive setup wizard:
68
202
 
69
203
  ```bash
70
204
  pnpm sync-translations init
71
205
  ```
72
206
 
73
- Dit maakt automatisch aan:
207
+ This automatically creates:
74
208
 
75
209
  ```
76
210
  src/lib/i18n/
77
- ├── settings.ts # i18next configuratie
78
- ├── types.ts # TypeScript types voor translations
211
+ ├── settings.ts # i18next configuration
212
+ ├── types.ts # TypeScript types for translations
79
213
  ├── client.ts # 'use client' hook + static imports
80
214
  ├── server.ts # Server component support
81
215
  ├── provider.tsx # Provider wrapper
82
216
  └── dictionaries/
83
- ├── en.json # Engels (leeg, wordt gevuld door pull)
84
- └── nl.json # Nederlands (leeg, wordt gevuld door pull)
217
+ ├── en.json # English (empty, filled by pull)
218
+ └── nl.json # Dutch (empty, filled by pull)
85
219
  ```
86
220
 
87
- Ook `.translationsrc.json` wordt gegenereerd:
221
+ Also `.translationsrc.json` is generated:
88
222
 
89
223
  ```json
90
224
  {
@@ -95,57 +229,56 @@ Ook `.translationsrc.json` wordt gegenereerd:
95
229
  }
96
230
  ```
97
231
 
98
- **Let op:** `routeParams` kan leeg blijven! De scanner genereert automatisch
99
- sensible defaults voor alle dynamic routes.
232
+ **Note:** `routeParams` can stay empty! The scanner automatically generates
233
+ sensible defaults for all dynamic routes.
100
234
 
101
- ## Stap 5: Eerste Sync — Keys Uploaden
235
+ ## Step 5: First Sync — Upload Keys
102
236
 
103
- Scan je code en upload gedetecteerde keys naar de CMS:
237
+ Scan your code and upload detected keys to the CMS:
104
238
 
105
239
  ```bash
106
240
  pnpm sync-translations sync
107
241
  ```
108
242
 
109
- Dit zal:
243
+ This will:
110
244
 
111
- 1. Je code scannen op translation keys (`t('namespace:key')` patroon)
112
- 2. Route detecteren waar elke key gebruikt wordt
113
- 3. Nieuwe keys naar CMS uploaden
114
- 4. Rapport tonen (welke keys toegevoegd/gewijzigd)
245
+ 1. Scan your code for translation keys (`t('namespace:key')` pattern)
246
+ 2. Detect routes where each key is used
247
+ 3. Upload new keys to CMS
248
+ 4. Show report (which keys added/changed)
115
249
 
116
- Controleer in de CMS of je keys verschenen zijn ✅
250
+ Check in the CMS if your keys appeared.
117
251
 
118
- **Bij eerste sync:** je krijgt mogelijk een error dat geen vertalingen kunnen
119
- worden gedownload dit is normaal! De keys zijn net geupload maar hebben nog
120
- geen vertalingen. Ga naar je CMS, vul vertalingen in, dan draai je `pull`
121
- opnieuw.
252
+ **On first sync:** you might get an error that no translations can be downloaded
253
+ this is normal! The keys were just uploaded but don't have translations yet.
254
+ Go to your CMS, fill in translations, then run `pull` again.
122
255
 
123
- ## Stap 5b: Vertalingen Toevoegen in CMS
256
+ ## Step 5b: Add Translations in CMS
124
257
 
125
- 1. Open je Translations CMS project
126
- 2. Je keys staan nu gelistd (zonder vertalingen)
127
- 3. Vul vertalingen in per locale (English, Nederlands, etc.)
128
- 4. Klik Save
258
+ 1. Open your Translations CMS project
259
+ 2. Your keys are now listed (without translations)
260
+ 3. Fill in translations per locale (English, Dutch, etc.)
261
+ 4. Click Save
129
262
 
130
- ## Stap 6: Vertalingen Ophalen
263
+ ## Step 6: Fetch Translations
131
264
 
132
- Als je de eerste sync hebt gedaan EN vertalingen in de CMS hebt ingevuld:
265
+ If you've done the first sync AND filled in translations in the CMS:
133
266
 
134
267
  ```bash
135
268
  pnpm sync-translations pull
136
269
  ```
137
270
 
138
- Dit haalt vertalingen op van de CMS en schrijft ze naar lokale JSON:
271
+ This fetches translations from the CMS and writes them to local JSON:
139
272
 
140
- - `dictionaries/en.json` → English vertalingen
141
- - `dictionaries/nl.json` → Nederlandse vertalingen
142
- - etc. (één per locale)
273
+ - `dictionaries/en.json` → English translations
274
+ - `dictionaries/nl.json` → Dutch translations
275
+ - etc. (one per locale)
143
276
 
144
- ## Stap 7: Integratie in je Project
277
+ ## Step 7: Integration in Your Project
145
278
 
146
279
  ### A. Root Layout Setup
147
280
 
148
- Voeg de provider toe aan je `src/app/layout.tsx`:
281
+ Add the provider to your `src/app/layout.tsx`:
149
282
 
150
283
  ```tsx
151
284
  import { TranslationProvider } from '@/lib/i18n/provider';
@@ -165,7 +298,7 @@ export default function RootLayout({
165
298
  }
166
299
  ```
167
300
 
168
- ### B. Server Components (Aanbevolen)
301
+ ### B. Server Components (Recommended)
169
302
 
170
303
  ```tsx
171
304
  import { getTranslation } from '@/lib/i18n/server';
@@ -195,22 +328,22 @@ export function MyButton() {
195
328
  }
196
329
  ```
197
330
 
198
- ### D. Multiple Namespaces (Met Type-Checking)
331
+ ### D. Multiple Namespaces (With Type-Checking)
199
332
 
200
333
  ```tsx
201
334
  const { t } = useTranslation(['common', 'auth']);
202
335
 
203
- // Dit werkt
336
+ // This works
204
337
  t('common:nav.home');
205
338
  t('auth:login.email');
206
339
 
207
- // Dit geeft een type error
208
- t('payments:amount'); // namespace niet toegevoegd
340
+ // This gives a type error
341
+ t('payments:amount'); // namespace not added
209
342
  ```
210
343
 
211
- ## Stap 8: Automatische Sync in je Workflow
344
+ ## Step 8: Automatic Sync in Your Workflow
212
345
 
213
- Voeg dit toe aan `package.json`:
346
+ Add this to `package.json`:
214
347
 
215
348
  ```json
216
349
  {
@@ -221,14 +354,14 @@ Voeg dit toe aan `package.json`:
221
354
  }
222
355
  ```
223
356
 
224
- Nu pull je automatisch de latest vertalingen bij startup
357
+ Now you automatically pull the latest translations on startup.
225
358
 
226
- ## Stap 9 (Optioneel): Preview Mode Instellen
359
+ ## Step 9 (Optional): Set Up Preview Mode
227
360
 
228
- Enable live in-context preview — editors kunnen live zien hoe hun tekst in je
229
- app eruit ziet.
361
+ Enable live in-context preview — editors can live see how their text looks in
362
+ your app.
230
363
 
231
- Voeg dit toe aan je root layout:
364
+ Add this to your root layout:
232
365
 
233
366
  ```tsx
234
367
  'use client';
@@ -240,7 +373,7 @@ export function CMSPreview() {
240
373
  if (process.env.NODE_ENV === 'development') {
241
374
  initPreviewListener({
242
375
  onLocaleSwitch: locale => {
243
- // wijzig taal als CMS een ander locale selecteert
376
+ // change language if CMS selects a different locale
244
377
  window.location.href = `/${locale}`;
245
378
  },
246
379
  });
@@ -250,7 +383,7 @@ export function CMSPreview() {
250
383
  }
251
384
  ```
252
385
 
253
- En voeg toe in layout:
386
+ And add to layout:
254
387
 
255
388
  ```tsx
256
389
  <TranslationProvider>
@@ -259,7 +392,7 @@ En voeg toe in layout:
259
392
  </TranslationProvider>
260
393
  ```
261
394
 
262
- Voeg `data-cms-key` toe op elementen voor nauwkeurige highlighting:
395
+ Add `data-cms-key` to elements for precise highlighting:
263
396
 
264
397
  ```tsx
265
398
  <h1 data-cms-key="common:page.title">{t('common:page.title')}</h1>
@@ -269,110 +402,122 @@ Voeg `data-cms-key` toe op elementen voor nauwkeurige highlighting:
269
402
 
270
403
  # CLI Commands Reference
271
404
 
272
- ## Basiscommands
405
+ ## Basic Commands
273
406
 
274
407
  ```bash
275
- # Scan code + upload naar CMS
408
+ # Scan code + upload to CMS
276
409
  pnpm sync-translations sync
277
410
 
278
- # Download vertalingen naar lokale JSON
411
+ # Download translations to local JSON
279
412
  pnpm sync-translations pull
280
413
 
281
- # Bekijk wat er zou veranderen (zonder upload)
414
+ # See what would change (without upload)
282
415
  pnpm sync-translations sync --dry-run
283
416
 
284
- # Bekijk verschil met vorige sync
417
+ # See difference from previous sync
285
418
  pnpm sync-translations status
286
419
 
287
- # Watch mode — auto-sync bij bestand wijzigingen
420
+ # Watch mode — auto-sync on file changes
288
421
  pnpm sync-translations watch
289
422
 
290
- # Interactieve setup
423
+ # Interactive setup
291
424
  pnpm sync-translations init
292
425
  ```
293
426
 
294
427
  ## Advanced Flags
295
428
 
296
- | Flag | Beschrijving |
297
- | ----------------- | ------------------------------------ |
298
- | `--dry-run` | Toon wijzigingen, voer niet uit |
299
- | `--force` | Negeer cache, force hernieuwen |
300
- | `--output <dir>` | Custom output map voor JSON |
301
- | `--env <name>` | Pull uit staging/production omgeving |
302
- | `--ttl <ms>` | Overschrijf cache TTL (ms) |
303
- | `--project-id` | Overschrijf project ID |
304
- | `--api-key` | Overschrijf API key |
305
- | `--cms-url` | Overschrijf CMS URL |
306
- | `--report <file>` | Schrijf sync rapport naar JSON file |
429
+ | Flag | Description |
430
+ | ----------------- | ---------------------------------------- |
431
+ | `--dry-run` | Show changes, don't execute |
432
+ | `--force` | Ignore cache, force refresh |
433
+ | `--output <dir>` | Custom output directory for JSON |
434
+ | `--env <name>` | Pull from staging/production environment |
435
+ | `--ttl <ms>` | Override cache TTL (ms) |
436
+ | `--project-id` | Override project ID |
437
+ | `--api-key` | Override API key |
438
+ | `--cms-url` | Override CMS URL |
439
+ | `--report <file>` | Write sync report to JSON file |
307
440
 
308
- ## Voorbeelden
441
+ ## Examples
309
442
 
310
443
  ```bash
311
- # Force refresh, negeer cache
444
+ # Force refresh, ignore cache
312
445
  pnpm sync-translations pull --force
313
446
 
314
447
  # Custom output directory
315
448
  pnpm sync-translations pull --output ./locales
316
449
 
317
- # Pull uit staging environment
450
+ # Pull from staging environment
318
451
  pnpm sync-translations pull --env staging
319
452
 
320
- # Schrijf rapport van wijzigingen
453
+ # Write report of changes
321
454
  pnpm sync-translations sync --report ./sync-report.json
322
455
  ```
323
456
 
324
457
  ---
325
458
 
326
- # Key Scanner — Hoe Werkt Het
459
+ # Key Scanner — How It Works
327
460
 
328
- De tool herkent deze patronen in je code:
461
+ The tool recognizes these patterns in your code:
329
462
 
330
463
  ```ts
331
- // React-i18next hook
464
+ // React-i18next hook
332
465
  const { t } = useTranslation('blog');
333
466
  t('blog:post.title');
334
467
 
335
- // Trans component
468
+ // Server-side helper
469
+ const { t } = await getTranslation('blog');
470
+ t('blog:post.title');
471
+
472
+ // CMS client helper
473
+ const t = await client.getTranslations(locale, 'blog');
474
+ t('blog:post.title');
475
+
476
+ // Trans component
336
477
  <Trans i18nKey="blog:post.title" />
337
478
 
338
- // String literal
339
- const key = 'blog:post.title';
479
+ // I18nKey-typed config (only if the file imports `I18nKey`)
480
+ import type { I18nKey } from '@/lib/i18n/types';
481
+ const label: I18nKey = 'sidebar:settings';
482
+
483
+ // Object properties ending in "Key"
484
+ const config = { titleKey: 'blog:post.title' };
340
485
  ```
341
486
 
342
487
  ### Format: `namespace:key`
343
488
 
344
- Alle keys moeten dit format volgen. Anders krijg je een warning:
489
+ All keys must follow this format. Otherwise you'll get a warning:
345
490
 
346
491
  ```ts
347
- // ✅ Goed
492
+ // Good
348
493
  t('common:button.save');
349
494
 
350
- // Fout — namespace mist
495
+ // Wrong — namespace missing
351
496
  t('save');
352
497
  ```
353
498
 
354
- ### Dynamische Routes — Auto-Generated routeParams
499
+ ### Dynamic Routes — Auto-Generated routeParams
355
500
 
356
- **Hoe het werkt:**
501
+ **How it works:**
357
502
 
358
- Bij elke `pnpm sync-translations sync`:
503
+ At each `pnpm sync-translations sync`:
359
504
 
360
- 1. Scanner detecteert automatisch alle routes met dynamic parameters (bijv.
505
+ 1. Scanner automatically detects all routes with dynamic parameters (e.g.
361
506
  `/[locale]/blog/[slug]`)
362
- 2. Voor elke `[param]` wordt automatisch een sensible default gegenereerd:
507
+ 2. For each `[param]` a sensible default is automatically generated:
363
508
  - `locale` / `lang` → `"en"`
364
509
  - `id`, `postId`, `productId` → `"123"`
365
510
  - `slug` → `"demo"`
366
511
  - `username` → `"demo-user"`
367
512
  - `email` → `"demo@example.com"`
368
- 3. Dit wordt opgeslagen in `.cms-sync-cache-meta.json` (mag je negeren)
369
- 4. De CMS gebruikt deze om werkende preview URLs te genereren
513
+ 3. This is saved in `.cms-sync-cache-meta.json` (you can ignore it)
514
+ 4. The CMS uses this to generate working preview URLs
370
515
 
371
- **Je hoeft niks te doen!** — alles werkt out-of-the-box.
516
+ **You don't have to do anything!** — everything works out-of-the-box.
372
517
 
373
- **Handmatig overschrijven (optioneel):**
518
+ **Manual override (optional):**
374
519
 
375
- Als je andere test-waarden wil gebruiken, vul je `.translationsrc.json` in:
520
+ If you want to use different test values, fill in `.translationsrc.json`:
376
521
 
377
522
  ```json
378
523
  {
@@ -383,21 +528,21 @@ Als je andere test-waarden wil gebruiken, vul je `.translationsrc.json` in:
383
528
  }
384
529
  ```
385
530
 
386
- Dit overschrijft de auto-generated waarden. Alles wat je hier toevoegt krijgt
387
- prioriteit.
531
+ This overrides the auto-generated values. Everything you add here takes
532
+ priority.
388
533
 
389
- ### Cache bestanden
534
+ ### Cache Files
390
535
 
391
- Bij elke sync worden twee cache bestanden aangemaakt:
536
+ At each sync two cache files are created:
392
537
 
393
- - `.cms-sync-cache.json` — Geüploade keys en hun routes (voor diff bij volgende
538
+ - `.cms-sync-cache.json` — Uploaded keys and their routes (for diff on next
394
539
  sync)
395
- - `.cms-sync-cache-meta.json` — Auto-generated route params (mag je .gitignore
396
- toevoegen)
540
+ - `.cms-sync-cache-meta.json` — Auto-generated route params (you can add to
541
+ .gitignore)
397
542
 
398
- ### Scanner Opties
543
+ ### Scanner Options
399
544
 
400
- Customize scan gedrag in `.translationsrc.json`:
545
+ Customize scan behavior in `.translationsrc.json`:
401
546
 
402
547
  ```json
403
548
  {
@@ -413,8 +558,8 @@ Customize scan gedrag in `.translationsrc.json`:
413
558
 
414
559
  ## Preview Mode — Live Highlighting
415
560
 
416
- Editors kunnen in de CMS klikken op "Show in app" en je app opent in een iframe
417
- met live highlighting van het element.
561
+ Editors can click "Show in app" in the CMS and your app opens in an iframe with
562
+ live highlighting of the element.
418
563
 
419
564
  ### Setup
420
565
 
@@ -435,7 +580,7 @@ useEffect(() => {
435
580
 
436
581
  ### Element Targeting
437
582
 
438
- Gebruik `data-cms-key` voor nauwkeurige targeting:
583
+ Use `data-cms-key` for precise targeting:
439
584
 
440
585
  ```tsx
441
586
  <h1 data-cms-key="blog:title">{t('blog:title')}</h1>
@@ -446,83 +591,83 @@ Gebruik `data-cms-key` voor nauwkeurige targeting:
446
591
 
447
592
  # JSON Output Format
448
593
 
449
- Na `sync-translations pull` worden dit soort bestanden gegenereerd:
594
+ After `sync-translations pull` these kinds of files are generated:
450
595
 
451
596
  ```json
452
597
  {
453
598
  "common": {
454
- "app.title": "Mijn App",
455
- "button.save": "Opslaan",
599
+ "app.title": "My App",
600
+ "button.save": "Save",
456
601
  "nav.home": "Home"
457
602
  },
458
603
  "auth": {
459
604
  "login.email": "Email",
460
- "login.password": "Wachtwoord"
605
+ "login.password": "Password"
461
606
  }
462
607
  }
463
608
  ```
464
609
 
465
- **Structuur:**
610
+ **Structure:**
466
611
 
467
612
  - Top-level keys = namespaces
468
613
  - Nested keys = translation strings
469
- - 1 bestand per taal (`en.json`, `nl.json`, etc.)
614
+ - 1 file per language (`en.json`, `nl.json`, etc.)
470
615
 
471
616
  ---
472
617
 
473
618
  # Troubleshooting
474
619
 
475
- ### Geen keys gevonden
620
+ ### No keys found
476
621
 
477
622
  ```bash
478
- # Check scanner configuratie
623
+ # Check scanner configuration
479
624
  pnpm sync-translations sync --dry-run
480
625
  ```
481
626
 
482
- Zorg dat je keys `namespace:key` format gebruiken.
627
+ Make sure your keys use `namespace:key` format.
483
628
 
484
- ### Environment variables niet gevonden
629
+ ### Environment variables not found
485
630
 
486
- Controleer `.env.local`:
631
+ Check `.env.local`:
487
632
 
488
633
  ```bash
489
634
  grep -E 'CMS_URL|CMS_PROJECT_ID|CMS_SYNC_API_KEY' .env.local
490
635
  ```
491
636
 
492
- Moet `NEXT_PUBLIC_CMS_URL`, `NEXT_PUBLIC_CMS_PROJECT_ID` en `CMS_SYNC_API_KEY`
493
- bevatten. De waarde van `CMS_SYNC_API_KEY` is een JWT token — haal deze op uit
494
- de CMS Project Settings.
637
+ Must contain `NEXT_PUBLIC_CMS_URL`, `NEXT_PUBLIC_CMS_PROJECT_ID` and
638
+ `CMS_SYNC_API_KEY`. The value of `CMS_SYNC_API_KEY` is a JWT token — get it from
639
+ the CMS Project Settings.
495
640
 
496
- ### Pull werkt niet
641
+ ### Pull doesn't work
497
642
 
498
643
  ```bash
499
- # Force refresh, negeer cache
644
+ # Force refresh, ignore cache
500
645
  pnpm sync-translations pull --force
501
646
 
502
- # Check configuratie
647
+ # Check configuration
503
648
  cat .translationsrc.json
504
649
  ```
505
650
 
506
651
  ### Type errors in TypeScript
507
652
 
508
- Zorg dat `src/lib/i18n/types.ts` correct gegenereerd is en dat je namespaces in
509
- `.translationsrc.json` staan.
653
+ Make sure `src/lib/i18n/types.ts` is generated correctly and that your
654
+ namespaces are in `.translationsrc.json`.
510
655
 
511
656
  ---
512
657
 
513
658
  # Best Practices
514
659
 
515
- 1. **Gebruik server components** waar mogelijkbeter voor performance
516
- 2. **Voeg `data-cms-key` toe** op visueel belangrijke elementen
517
- 3. **Commit `.translationsrc.json`** naar git — niet `.env.local`
518
- 4. **Negeer cache bestanden:** voeg toe aan `.gitignore`:
660
+ 1. **Use server components** where possiblebetter for performance
661
+ 2. **Add `data-cms-key`** on visually important elements
662
+ 3. **Commit `.translationsrc.json`** to git — not `.env.local`
663
+ 4. **Ignore cache files:** add to `.gitignore`:
519
664
  ```
520
665
  .cms-sync-cache.json
521
666
  .cms-sync-cache-meta.json
522
667
  .last-pulled
523
668
  ```
524
- 5. **Run `sync` in CI/CD** op main branch — catch missing translations
525
- 6. **Voeg `pull` toe aan build script** — altijd fresh translations
669
+ 5. **Run `sync` in CI/CD** on main branch — catch missing translations
670
+ 6. **Add `pull` to build script** — always fresh translations
526
671
 
527
672
  ---
528
673