AUXteam commited on
Commit
a536ee9
·
verified ·
1 Parent(s): e0ff61f

Upload TRANSLATION.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. TRANSLATION.md +606 -0
TRANSLATION.md ADDED
@@ -0,0 +1,606 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🌍 Translation Guide for BentoPDF
2
+
3
+ This guide will help you add new languages or improve existing translations for BentoPDF.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [Quick Start](#quick-start)
9
+ - [Adding a New Language](#adding-a-new-language)
10
+ - [Translation File Structure](#translation-file-structure)
11
+ - [Where Translations Are Used](#where-translations-are-used)
12
+ - [Testing Your Translations](#testing-your-translations)
13
+ - [Translation Guidelines](#translation-guidelines)
14
+ - [Common Issues](#common-issues)
15
+
16
+ ---
17
+
18
+ ## Overview
19
+
20
+ BentoPDF uses **i18next** for internationalization (i18n). Currently supported languages:
21
+
22
+ - **English** (`en`) - Default
23
+ - **Belarusian** (`be`)
24
+ - **German** (`de`)
25
+ - **Spanish** (`es`)
26
+ - **French** (`fr`)
27
+ - **Italian** (`it`)
28
+ - **Portuguese** (`pt`)
29
+ - **Turkish** (`tr`)
30
+ - **Vietnamese** (`vi`)
31
+ - **Indonesian** (`id`)
32
+ - **Chinese** (`zh`)
33
+ - **Traditional Chinese (Taiwan)** (`zh-TW`)
34
+
35
+ The app automatically detects the language from the URL path:
36
+
37
+ - `/` or `/en/` → English (default)
38
+ - `/de/` → German
39
+ - `/fr/` → French
40
+ - etc.
41
+
42
+ ### Architecture
43
+
44
+ BentoPDF uses a **static pre-rendering** approach for SEO-optimized i18n:
45
+
46
+ 1. **Build time**: `scripts/generate-i18n-pages.mjs` generates localized HTML files in `dist/{lang}/`
47
+ 2. **Dev/Preview**: `languageRouterPlugin` in `vite.config.ts` handles URL rewriting
48
+ 3. **Production**: Nginx serves static files directly from language directories
49
+
50
+ ---
51
+
52
+ ## Quick Start
53
+
54
+ **To improve existing translations:**
55
+
56
+ 1. Navigate to `public/locales/{language}/common.json` and `public/locales/{language}/tools.json`
57
+ 2. Find the key you want to update
58
+ 3. Change the translation value
59
+ 4. Save and test
60
+
61
+ **To add a new language (e.g., Japanese `ja`):**
62
+
63
+ 1. Copy `public/locales/en/` to `public/locales/ja/`
64
+ 2. Translate all values in both `ja/common.json` and `ja/tools.json`
65
+ 3. Add Japanese to `supportedLanguages` and `languageNames` in `src/js/i18n/i18n.ts`
66
+ 4. Add `'ja'` to `SUPPORTED_LANGUAGES` in `vite.config.ts`
67
+ 5. Restart the dev server
68
+ 6. Run `npm run build` to generate static language pages
69
+ 7. Test thoroughly
70
+
71
+ ---
72
+
73
+ ## Adding a New Language
74
+
75
+ Let's add **Spanish** as an example:
76
+
77
+ ### Step 1: Create Translation Files
78
+
79
+ ```bash
80
+ # Create the directory
81
+ mkdir -p public/locales/es
82
+
83
+ # Copy the English template
84
+ cp public/locales/en/common.json public/locales/es/common.json
85
+ ```
86
+
87
+ ### Step 2: Translate the JSON Files
88
+
89
+ Open `public/locales/es/common.json` and translate all the values:
90
+
91
+ ```json
92
+ {
93
+ "nav": {
94
+ "home": "Inicio",
95
+ "about": "Acerca de",
96
+ "contact": "Contacto",
97
+ "allTools": "Todas las herramientas"
98
+ },
99
+ "hero": {
100
+ "title": "Tu conjunto de herramientas PDF gratuito y seguro",
101
+ "subtitle": "Combina, divide, comprime y edita archivos PDF directamente en tu navegador."
102
+ }
103
+ // ... continue translating all keys
104
+ }
105
+ ```
106
+
107
+ ⚠️ **Important**: Only translate the **values**, NOT the keys!
108
+
109
+ ✅ **Correct:**
110
+
111
+ ```json
112
+ "home": "Inicio"
113
+ ```
114
+
115
+ ❌ **Wrong:**
116
+
117
+ ```json
118
+ "inicio": "Inicio"
119
+ ```
120
+
121
+ Then do the same for `public/locales/fr/tools.json` to translate all tool names and descriptions.
122
+
123
+ ### Step 3: Register the Language
124
+
125
+ Edit `src/js/i18n/i18n.ts`:
126
+
127
+ ```typescript
128
+ // Add 'fr' to supported languages
129
+ export const supportedLanguages = ['en', 'de', 'es', 'fr', 'zh', 'vi'] as const;
130
+ export type SupportedLanguage = (typeof supportedLanguages)[number];
131
+
132
+ // Add French display name
133
+ export const languageNames: Record<SupportedLanguage, string> = {
134
+ en: 'English',
135
+ de: 'Deutsch',
136
+ fr: 'Français', // ← Add this
137
+ };
138
+ ```
139
+
140
+ ### Step 4: Update Vite Configuration
141
+
142
+ In `vite.config.ts`, add your language to the `SUPPORTED_LANGUAGES` array:
143
+
144
+ ```typescript
145
+ const SUPPORTED_LANGUAGES = [
146
+ 'en',
147
+ 'de',
148
+ 'es',
149
+ 'zh',
150
+ 'zh-TW',
151
+ 'vi',
152
+ 'it',
153
+ 'id',
154
+ 'tr',
155
+ 'fr',
156
+ 'pt',
157
+ 'ja',
158
+ ] as const;
159
+ ```
160
+
161
+ > **Important**: This is required for both dev server routing and the build-time i18n generation.
162
+
163
+ ### Step 5: Test Your Translation
164
+
165
+ ```bash
166
+ # Restart the dev server
167
+ npm run dev
168
+
169
+ # Visit the Japanese version
170
+ # http://localhost:5173/ja/
171
+ ```
172
+
173
+ ### Step 6: Build and Verify Static Files
174
+
175
+ ```bash
176
+ # Run build (includes i18n page generation)
177
+ npm run build
178
+
179
+ # Verify files were created
180
+ ls dist/ja/
181
+ # Should show: index.html, merge-pdf.html, etc.
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Translation File Structure
187
+
188
+ The `common.json` file is organized into logical sections:
189
+
190
+ ```json
191
+ {
192
+ "nav": {
193
+ // Navigation menu items
194
+ },
195
+ "hero": {
196
+ // Homepage hero section
197
+ },
198
+ "features": {
199
+ // Features section
200
+ },
201
+ "tools": {
202
+ // Tool names and descriptions
203
+ },
204
+ "upload": {
205
+ // File upload UI
206
+ },
207
+ "settings": {
208
+ // Settings modal and keyboard shortcuts
209
+ },
210
+ "faq": {
211
+ // FAQ section
212
+ },
213
+ "footer": {
214
+ // Footer links and text
215
+ },
216
+ "compliance": {
217
+ // Security compliance information
218
+ },
219
+ "testimonials": {
220
+ // User testimonials
221
+ },
222
+ "support": {
223
+ // Support section
224
+ },
225
+ "alert": {
226
+ // Alert and error messages
227
+ }
228
+ }
229
+ ```
230
+
231
+ ### Key Naming Convention
232
+
233
+ - Use **camelCase** for keys: `"deletePage"` not `"delete_page"`
234
+ - Use **nested objects** for organization: `"nav.home"` is represented as:
235
+ ```json
236
+ {
237
+ "nav": {
238
+ "home": "Home"
239
+ }
240
+ }
241
+ ```
242
+ - Be descriptive: `"shortcutsWarning"` is better than `"warning1"`
243
+
244
+ ---
245
+
246
+ ## Where Translations Are Used
247
+
248
+ ### 1. HTML Templates (`data-i18n` attribute)
249
+
250
+ ```html
251
+ <!-- Translation key: nav.home -->
252
+ <a href="/" data-i18n="nav.home">Home</a>
253
+ ```
254
+
255
+ The `data-i18n` attribute tells i18next which translation to use.
256
+
257
+ ### 2. Tool Definitions
258
+
259
+ Tool names and descriptions are defined in `src/js/config/tools.ts` and use a special namespace:
260
+
261
+ ```typescript
262
+ {
263
+ name: 'Merge PDF', // Used for shortcuts only
264
+ subtitle: 'Combine multiple PDFs into one file.',
265
+ }
266
+ ```
267
+
268
+ In translations:
269
+
270
+ ```json
271
+ {
272
+ "tools": {
273
+ "mergePdf": {
274
+ "name": "PDF zusammenführen",
275
+ "subtitle": "Mehrere PDFs in eine Datei kombinieren."
276
+ }
277
+ }
278
+ }
279
+ ```
280
+
281
+ ### 3. Dynamic JavaScript (`t()` function)
282
+
283
+ For translations that need to be applied dynamically:
284
+
285
+ ```typescript
286
+ import { t } from './i18n/i18n';
287
+
288
+ const message = t('alert.error');
289
+ console.log(message); // "Error" or "Fehler" depending on language
290
+ ```
291
+
292
+ ### 4. Placeholders
293
+
294
+ For input placeholders:
295
+
296
+ ```html
297
+ <input
298
+ type="text"
299
+ placeholder="Search for a tool..."
300
+ data-i18n-placeholder="tools.searchPlaceholder"
301
+ />
302
+ ```
303
+
304
+ In `common.json`:
305
+
306
+ ```json
307
+ {
308
+ "tools": {
309
+ "searchPlaceholder": "Nach einem Tool suchen..."
310
+ }
311
+ }
312
+ ```
313
+
314
+ ---
315
+
316
+ ## Testing Your Translations
317
+
318
+ ### Manual Testing
319
+
320
+ 1. **Start development server:**
321
+
322
+ ```bash
323
+ npm run dev
324
+ ```
325
+
326
+ 2. **Visit each language:**
327
+ - English: `http://localhost:5173/en/`
328
+ - German: `http://localhost:5173/de/`
329
+ - Vietnamese: `http://localhost:5173/vi/`
330
+ - Indonesian: `http://localhost:5173/id/`
331
+ - Chinese: `http://localhost:5173/zh/`
332
+ - Traditional Chinese (Taiwan): `http://localhost:5173/zh-TW/`
333
+ - French: `http://localhost:5173/fr/`
334
+ - Your new language: `http://localhost:5173/es/`
335
+
336
+ 3. **Check these pages:**
337
+ - Homepage (`/`)
338
+ - About page (`/about.html`)
339
+ - Contact page (`/contact.html`)
340
+ - FAQ page (`/faq.html`)
341
+ - Tool pages (e.g., `/merge-pdf.html`)
342
+
343
+ 4. **Test these interactions:**
344
+ - Click the language switcher in the footer
345
+ - Navigate between pages
346
+ - Open the settings modal (click gear icon next to search)
347
+ - Try a tool to see upload messages
348
+
349
+ ### Automated Checks
350
+
351
+ Check for missing translations:
352
+
353
+ ```bash
354
+ # This will show any missing keys
355
+ node scripts/check-translations.js
356
+ ```
357
+
358
+ _(If this script doesn't exist, you may need to create it or manually compare JSON files)_
359
+
360
+ ### Browser Testing
361
+
362
+ Test in different browsers:
363
+
364
+ - Chrome/Edge
365
+ - Firefox
366
+ - Safari
367
+
368
+ ---
369
+
370
+ ## Translation Guidelines
371
+
372
+ ### 1. Keep the Tone Consistent
373
+
374
+ BentoPDF is **friendly, clear, and professional**. Match this tone in your translations.
375
+
376
+ ✅ **Good:**
377
+
378
+ ```json
379
+ "hero.title": "Ihr kostenloses und sicheres PDF-Toolkit"
380
+ ```
381
+
382
+ ❌ **Too formal:**
383
+
384
+ ```json
385
+ "hero.title": "Ihr gebührenfreies und gesichertes Werkzeug für PDF-Dokumente"
386
+ ```
387
+
388
+ ### 2. Preserve Formatting
389
+
390
+ Some strings contain HTML or special characters:
391
+
392
+ ```json
393
+ {
394
+ "faq.analytics.answer": "We care about your privacy. BentoPDF does not track personal information. We use <a href=\"https://simpleanalytics.com\" class=\"text-indigo-400 hover:underline\" target=\"_blank\" rel=\"noopener noreferrer\">Simple Analytics</a> solely to see anonymous visit counts."
395
+ }
396
+ ```
397
+
398
+ When translating, **keep the HTML tags intact**:
399
+
400
+ ```json
401
+ {
402
+ "faq.analytics.answer": "Wir schätzen Ihre Privatsphäre. BentoPDF verfolgt keine persönlichen Informationen. Wir verwenden <a href=\"https://simpleanalytics.com\" class=\"text-indigo-400 hover:underline\" target=\"_blank\" rel=\"noopener noreferrer\">Simple Analytics</a> ausschließlich, um anonyme Besucherzahlen zu sehen."
403
+ }
404
+ ```
405
+
406
+ ### 3. Handle Plurals and Gender
407
+
408
+ If your language has complex plural rules or gender distinctions, consult the [i18next pluralization guide](https://www.i18next.com/translation-function/plurals).
409
+
410
+ Example:
411
+
412
+ ```json
413
+ {
414
+ "pages": "page",
415
+ "pages_plural": "pages"
416
+ }
417
+ ```
418
+
419
+ ### 4. Don't Translate Brand Names or Legal Terms
420
+
421
+ Keep these as-is:
422
+
423
+ - BentoPDF
424
+ - PDF
425
+ - GitHub
426
+ - Discord
427
+ - Chrome, Firefox, Safari, etc.
428
+ - Terms and Conditions
429
+ - Privacy Policy
430
+ - Licensing
431
+
432
+ ### 5. Technical Terms
433
+
434
+ For technical terms, use commonly accepted translations in your language:
435
+
436
+ - "Merge" → "Fusionner" (French), "Zusammenführen" (German)
437
+ - "Split" → "Diviser" (French), "Teilen" (German)
438
+ - "Compress" → "Compresser" (French), "Komprimieren" (German)
439
+
440
+ If unsure, check how other PDF tools translate these terms in your language.
441
+
442
+ ### 6. String Length
443
+
444
+ Some UI elements have limited space. Try to keep translations **similar in length** to the English version.
445
+
446
+ If a translation is much longer, test it visually to ensure it doesn't break the layout.
447
+
448
+ ---
449
+
450
+ ## Common Issues
451
+
452
+ ### Issue: Translations Not Showing Up
453
+
454
+ **Solution:**
455
+
456
+ 1. Clear your browser cache
457
+ 2. Hard refresh (Ctrl+F5 or Cmd+Shift+R)
458
+ 3. Check browser console for errors
459
+ 4. Verify the JSON file is valid (no syntax errors)
460
+
461
+ ### Issue: Some Text Still in English
462
+
463
+ **Possible causes:**
464
+
465
+ 1. Missing translation key in your language file
466
+ 2. Missing `data-i18n` attribute in HTML
467
+ 3. Hardcoded text in JavaScript
468
+
469
+ **Solution:**
470
+
471
+ - Compare your language file with `en/common.json` to find missing keys
472
+ - Search the codebase for hardcoded strings
473
+
474
+ ### Issue: JSON Syntax Error
475
+
476
+ **Symptoms:**
477
+
478
+ ```
479
+ SyntaxError: Unexpected token } in JSON at position 1234
480
+ ```
481
+
482
+ **Solution:**
483
+
484
+ - Use a JSON validator: https://jsonlint.com/
485
+ - Common mistakes:
486
+ - Trailing comma after last item
487
+ - Missing or extra quotes
488
+ - Unescaped quotes inside strings (use `\"`)
489
+
490
+ ### Issue: Language Switcher Not Showing New Language
491
+
492
+ **Solution:**
493
+ Make sure you added the language to both arrays in `i18n.ts`:
494
+
495
+ ```typescript
496
+ export const supportedLanguages = ['en', 'de', 'es', 'fr', 'zh', 'vi']; // ← Add here
497
+ export const languageNames = {
498
+ en: 'English',
499
+ de: 'Deutsch',
500
+ es: 'Español',
501
+ fr: 'Français', // ← And here
502
+ zh: '中文',
503
+ vi: 'Tiếng Việt',
504
+ };
505
+ ```
506
+
507
+ ### Issue: 404 Error When Accessing Language Pages
508
+
509
+ **Symptoms:**
510
+ Visiting `http://localhost:5173/ja/about.html` shows a 404 error page.
511
+
512
+ **Solution:**
513
+ You need to add your language code to `SUPPORTED_LANGUAGES` in `vite.config.ts`:
514
+
515
+ ```typescript
516
+ const SUPPORTED_LANGUAGES = [
517
+ 'en',
518
+ 'de',
519
+ 'es',
520
+ 'zh',
521
+ 'zh-TW',
522
+ 'vi',
523
+ 'it',
524
+ 'id',
525
+ 'tr',
526
+ 'fr',
527
+ 'pt',
528
+ 'ja',
529
+ ] as const;
530
+ ```
531
+
532
+ After updating, restart the dev server:
533
+
534
+ ```bash
535
+ npm run dev
536
+ ```
537
+
538
+ ---
539
+
540
+ ## File Checklist
541
+
542
+ When adding a new language, make sure these files are updated:
543
+
544
+ - [ ] `public/locales/{lang}/common.json` - Main translation file
545
+ - [ ] `public/locales/{lang}/tools.json` - Tools translation file
546
+ - [ ] `src/js/i18n/i18n.ts` - Add to `supportedLanguages` and `languageNames`
547
+ - [ ] `vite.config.ts` - Add to `SUPPORTED_LANGUAGES` array
548
+ - [ ] Test all pages: homepage, about, contact, FAQ, tool pages
549
+ - [ ] Test settings modal and shortcuts
550
+ - [ ] Test language switcher in footer
551
+ - [ ] Verify URL routing works (`/{lang}/`)
552
+ - [ ] Run `npm run build` and verify `dist/{lang}/` folder is created
553
+ - [ ] Test that all tools load correctly
554
+
555
+ ---
556
+
557
+ ## Getting Help
558
+
559
+ If you have questions or need help:
560
+
561
+ 1. Check existing translations in `public/locales/de/common.json` for reference
562
+ 2. Open an issue on [GitHub](https://github.com/alam00000/bentopdf/issues)
563
+ 3. Join our [Discord server](https://discord.gg/Bgq3Ay3f2w)
564
+
565
+ ---
566
+
567
+ ## Contributing Your Translation
568
+
569
+ Once you've completed a translation:
570
+
571
+ 1. **Test thoroughly** (see [Testing Your Translations](#testing-your-translations))
572
+ 2. **Fork the repository** on GitHub
573
+ 3. **Create a new branch**: `git checkout -b add-french-translation`
574
+ 4. **Commit your changes**: `git commit -m "Add French translation"`
575
+ 5. **Push to your fork**: `git push origin add-french-translation`
576
+ 6. **Open a Pull Request** with:
577
+ - Description of the language added
578
+ - Screenshots showing the translation in action
579
+ - Confirmation that you've tested all pages
580
+
581
+ Thank you for contributing to BentoPDF! 🎉
582
+
583
+ ---
584
+
585
+ ## Translation Progress
586
+
587
+ Current translation coverage:
588
+
589
+ | Language | Code | Status | Maintainer |
590
+ | ------------------- | ------- | -------------- | ---------- |
591
+ | English | `en` | ✅ Complete | Core team |
592
+ | German | `de` | ✅ Complete | Community |
593
+ | Spanish | `es` | ✅ Complete | Community |
594
+ | French | `fr` | ✅ Complete | Community |
595
+ | Italian | `it` | ✅ Complete | Community |
596
+ | Portuguese | `pt` | ✅ Complete | Community |
597
+ | Turkish | `tr` | ✅ Complete | Community |
598
+ | Vietnamese | `vi` | ✅ Complete | Community |
599
+ | Indonesian | `id` | ✅ Complete | Community |
600
+ | Chinese | `zh` | ✅ Complete | Community |
601
+ | Traditional Chinese | `zh-TW` | ✅ Complete | Community |
602
+ | Your Language | `??` | 🚧 In Progress | You? |
603
+
604
+ ---
605
+
606
+ **Last Updated**: January 2026