19 KiB
i18n — Panduan Internasionalisasi (Bahasa Indonesia)
🌐 Languages: 🇺🇸 English · 🇸🇦 ar · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇪🇸 es · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇳 gu · 🇮🇱 he · 🇮🇳 hi · 🇭🇺 hu · 🇮🇩 id · 🇮🇹 it · 🇯🇵 ja · 🇰🇷 ko · 🇮🇳 mr · 🇲🇾 ms · 🇳🇱 nl · 🇳🇴 no · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇸🇰 sk · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇻🇳 vi · 🇨🇳 zh-CN
OmniRoute mendukung 30 bahasa dengan terjemahan UI dashboard penuh, dokumentasi yang diterjemahkan, dan dukungan RTL untuk bahasa Arab dan Ibrani.
Referensi Cepat
| Tugas | Perintah |
|---|---|
| Hasilkan terjemahan | node scripts/i18n/generate-multilang.mjs messages |
| Terjemahkan dokumentasi (LLM) | python3 scripts/i18n_autotranslate.py --api-url <url> --api-key <key> --model <model> |
| Validasi lokal | python3 scripts/validate_translation.py quick -l cs |
| Periksa kunci kode | python3 scripts/check_translations.py |
| Hasilkan laporan QA | node scripts/i18n/generate-qa-checklist.mjs |
| QA Visual (Playwright) | node scripts/i18n/run-visual-qa.mjs |
Arsitektur
Sumber Kebenaran
- String UI:
src/i18n/messages/en.json(sumber bahasa Inggris, ~2800 kunci) - File lokal:
src/i18n/messages/{locale}.json(30 terjemahan) - Framework:
next-intldengan resolusi lokal berbasis cookie - Konfigurasi:
src/i18n/config.ts— mendefinisikan semua 30 lokal, nama bahasa, bendera
Alur Runtime
- Pengguna memilih bahasa → cookie
NEXT_LOCALEdisetel src/i18n/request.tsmenyelesaikan lokal: cookie → headerAccept-Language→ fallbacken- Import dinamis memuat
messages/{locale}.json - Komponen menggunakan
useTranslations("namespace")dant("key")
Lokal yang Didukung
| Kode | Bahasa | RTL | Kode Google Translate |
|---|---|---|---|
ar |
العربية | Ya | ar |
bg |
Български | Tidak | bg |
cs |
Čeština | Tidak | cs |
da |
Dansk | Tidak | da |
de |
Deutsch | Tidak | de |
es |
Español | Tidak | es |
fi |
Suomi | Tidak | fi |
fr |
Français | Tidak | fr |
he |
עברית | Ya | iw |
hi |
हिन्दी | Tidak | hi |
hu |
Magyar | Tidak | hu |
id |
Bahasa Indonesia | Tidak | id |
it |
Italiano | Tidak | it |
ja |
日本語 | Tidak | ja |
ko |
한국어 | Tidak | ko |
ms |
Bahasa Melayu | Tidak | ms |
nl |
Nederlands | Tidak | nl |
no |
Norsk | Tidak | no |
phi |
Filipino | Tidak | tl |
pl |
Polski | Tidak | pl |
pt |
Português (Portugal) | Tidak | pt |
pt-BR |
Português (Brasil) | Tidak | pt |
ro |
Română | Tidak | ro |
ru |
Русский | Tidak | ru |
sk |
Slovenčina | Tidak | sk |
sv |
Svenska | Tidak | sv |
th |
ไทย | Tidak | th |
tr |
Türkçe | Tidak | tr |
uk-UA |
Українська | Tidak | uk |
vi |
Tiếng Việt | Tidak | vi |
zh-CN |
中文 (简体) | Tidak | zh-CN |
Menambahkan Bahasa Baru
1. Daftarkan Lokal
Edit src/i18n/config.ts:
// Add to LOCALES array
"xx",
// Add to LANGUAGES array
{ code: "xx", label: "XX", name: "Language Name", flag: "🏳️" },
2. Tambahkan ke Generator
Edit scripts/i18n/generate-multilang.mjs — tambahkan entri ke LOCALE_SPECS:
{
code: "xx",
googleTl: "xx",
label: "XX",
flag: "🏳️",
languageName: "Language Name",
readmeName: "Language Name",
docsName: "Language Name",
},
3. Hasilkan Terjemahan Awal
node scripts/i18n/generate-multilang.mjs messages
Perintah ini membuat src/i18n/messages/xx.json yang diterjemahkan secara otomatis dari en.json melalui Google Translate.
4. Tinjau & Perbaiki Terjemahan Otomatis
Terjemahan otomatis hanyalah titik awal. Tinjau secara manual untuk:
- Ketepatan teknis
- Terminologi yang sesuai konteks
- Penanganan placeholder yang benar (
{count},{value}, dll.)
5. Validasi
python3 scripts/validate_translation.py quick -l xx
python3 scripts/validate_translation.py diff common -l xx
6. Hasilkan Dokumentasi yang Diterjemahkan
node scripts/i18n/generate-multilang.mjs docs
Pipeline Terjemahan Otomatis
generate-multilang.mjs (Google Translate)
Mesin terjemahan otomatis utama — menggunakan API gratis Google Translate untuk menghasilkan terjemahan string UI, README, dan dokumentasi.
node scripts/i18n/generate-multilang.mjs [messages|readme|docs|all]
| Mode | Yang dilakukan |
|---|---|
messages |
Menerjemahkan kunci yang hilang di src/i18n/messages/{locale}.json dari en.json |
readme |
Menerjemahkan README.md ke semua lokal sebagai README.{code}.md di root proyek |
docs |
Menerjemahkan DOC_SOURCE_FILES ke docs/i18n/{locale}/{docName} |
all |
Menjalankan ketiga mode sekaligus |
Fitur:
- Perlindungan teks: Menyembunyikan blok kode (
```), kode inline (`), tautan/gambar markdown ([text](url)), tag HTML, tabel, dan placeholder ICU ({count},{value},{total}, dll.) sebelum penerjemahan, lalu memulihkannya - Pemrosesan bertahap: Menggabungkan beberapa string dengan pemisah
__OMNIROUTE_I18N_SEPARATOR__untuk meminimalkan panggilan API (maks 1800 karakter per permintaan) - Cache dalam memori: Menghindari panggilan API yang redundan untuk string yang berulang dalam satu sesi
- Logika percobaan ulang: Backoff eksponensial (hingga 5 percobaan dengan penundaan 300ms × percobaan) untuk error 429/5xx
- Batas waktu: 20 detik per permintaan
- Lewati yang sudah ada: Jika file target sudah ada, file tersebut TIDAK akan ditimpa
Perilaku penting:
docs/i18n/README.mddihasilkan ulang setiap kali dijalankan — ini adalah indeks dokumentasi yang dibuat otomatis- File
README.{code}.mddi root hanya dibuat jika belum ada (melewati lokal yang ada diEXISTING_README_CODES) - Bilah bahasa (
🌐 **Languages:** ...) disisipkan/diperbarui secara otomatis di semua dokumen yang diterjemahkan
i18n_autotranslate.py (berbasis LLM)
Penerjemah sekunder — menggunakan API LLM yang kompatibel dengan OpenAI (termasuk OmniRoute sendiri) untuk menerjemahkan file markdown docs/i18n/ yang sudah ada. Paling baik digunakan untuk menyempurnakan atau menerjemahkan ulang dokumen dengan kualitas yang lebih baik dari Google Translate.
python3 scripts/i18n_autotranslate.py \
--api-url http://localhost:20128/v1 \
--api-key sk-your-key \
--model gpt-4o
Fitur:
- Memindai file markdown
docs/i18n/untuk paragraf berbahasa Inggris - Melewati blok kode, tabel, dan konten yang sudah diterjemahkan
- Mengirimkan paragraf ke LLM dengan prompt sistem penerjemahan teknis
- Mendukung semua 30 bahasa
Validasi & QA
validate_translation.py
Validator terjemahan — membandingkan JSON lokal mana pun dengan en.json dan melaporkan masalah yang ditemukan.
# Quick check (counts only)
python3 scripts/validate_translation.py quick -l cs
# Output:
# Missing: 0
# Untranslated: 0
# Ignored (UNTRANSLATABLE_KEYS): 236
# Detailed diff by category
python3 scripts/validate_translation.py diff common -l cs
python3 scripts/validate_translation.py diff settings -l cs
# Export to CSV
python3 scripts/validate_translation.py csv -l cs > report.csv
# Export to Markdown
python3 scripts/validate_translation.py md -l cs > report.md
# Full report (default)
python3 scripts/validate_translation.py -l cs
Yang dideteksi:
- Kunci yang hilang — kunci yang ada di
en.jsontetapi tidak ada di file lokal - Kunci tambahan — kunci yang ada di file lokal tetapi tidak ada di
en.json - Kunci yang belum diterjemahkan — kunci yang nilai lokalnya sama dengan sumber bahasa Inggris (tidak termasuk daftar yang diizinkan)
- Ketidaksesuaian placeholder — placeholder ICU yang tidak cocok antara sumber dan terjemahan
Kode keluar:
| Kode | Makna |
|---|---|
| 0 | OK |
| 1 | Error umum |
| 2 | String yang hilang (error kritis) |
| 3 | Peringatan belum diterjemahkan (lunak) |
Lingkungan: Setel TRANSLATION_LANG=cs atau gunakan flag -l cs.
check_translations.py
Pemeriksa kunci kode ke JSON — memindai src/**/*.tsx dan src/**/*.ts untuk panggilan useTranslations() dan memverifikasi bahwa semua kunci yang direferensikan ada di en.json.
# Basic check
python3 scripts/check_translations.py
# Verbose output
python3 scripts/check_translations.py --verbose
# Auto-fix (adds missing keys to en.json)
python3 scripts/check_translations.py --fix
generate-qa-checklist.mjs
QA analisis statis — memindai file halaman Next.js untuk metrik risiko i18n dan menghasilkan laporan Markdown.
node scripts/i18n/generate-qa-checklist.mjs
Yang diperiksa:
- Penggunaan kelas lebar tetap (risiko overflow)
- Kelas arah kiri/kanan (risiko RTL)
- Pola rentan terpotong
- Paritas lokal (kunci yang hilang/tambahan vs
en.json) - Bilah pemilih bahasa README di lokal prioritas (
es,fr,de,ja,ar)
Keluaran: docs/reports/i18n-qa-checklist-{date}.md
run-visual-qa.mjs
QA visual melalui Playwright — mengambil tangkapan layar semua rute dashboard dalam beberapa lokal dan viewport, lalu mengevaluasi kesehatan halaman.
# Default: es, fr, de, ja, ar on localhost:20128
node scripts/i18n/run-visual-qa.mjs
# Custom base URL and locales
QA_BASE_URL=http://staging.example.com QA_LOCALES=de,fr node scripts/i18n/run-visual-qa.mjs
# Custom routes
QA_ROUTES=/dashboard/settings,/dashboard/providers node scripts/i18n/run-visual-qa.mjs
Yang dideteksi:
- Teks yang meluap (text overflow)
- Elemen yang terpotong
- Ketidaksesuaian tata letak RTL
Keluaran: docs/reports/i18n-visual-qa-{date}.md + laporan JSON
Mengelola Kunci yang Tidak Dapat Diterjemahkan
untranslatable-keys.json
File: scripts/i18n/untranslatable-keys.json
Daftar yang diizinkan berisi kunci yang harus tetap identik dengan sumber bahasa Inggris. Digunakan oleh validate_translation.py untuk menghindari peringatan "belum diterjemahkan" yang merupakan positif palsu.
{
"description": "Keys that should remain untranslated...",
"keys": [
"common.model",
"common.oauth",
"health.cpu",
...
]
}
Yang termasuk di sini:
- Nama merek/produk:
landing.brandName,common.social-github - Istilah teknis/akronim:
health.cpu,mcpDashboard.pid,settings.ai - String ICU/format:
apiManager.modelsCount,health.millisecondsShort - Nilai placeholder:
providers.openaiBaseUrlPlaceholder,cliTools.baseUrlPlaceholder - Nama protokol:
common.http,common.oauth,providers.oauth2Label - Bagian navigasi:
sidebar.primarySection,sidebar.cliSection
Untuk menambahkan kunci: Edit array keys di scripts/i18n/untranslatable-keys.json dan jalankan ulang validasi.
Integrasi CI
GitHub Actions (.github/workflows/ci.yml)
Pipeline CI memvalidasi semua lokal pada setiap push dan PR:
- Job
i18n-matrix— secara dinamis menemukan semua file lokal (tidak termasuken.json) - Job
i18n— menjalankanvalidate_translation.py quick -l '<lang>'untuk setiap lokal secara paralel - Job
ci-summary— mengagregasi hasil menjadi ringkasan dashboard
# i18n-matrix: discovers languages
LANGS=$(ls src/i18n/messages/*.json | xargs -n1 basename | sed 's/.json$//' | grep -v '^en$')
# i18n: validates each language
python3 scripts/validate_translation.py quick -l '${{ matrix.lang }}'
Keluaran dashboard:
## 🌍 Translations
| Metric | Value |
|--------|------|
| Languages checked | 30 |
| Total untranslated | 0 |
✅ All translations complete
Struktur File
src/i18n/
├── config.ts # Definisi lokal (30 lokal, konfigurasi RTL)
├── request.ts # Resolusi lokal saat runtime
└── messages/
├── en.json # Sumber kebenaran (~2800 kunci)
├── cs.json # Terjemahan bahasa Ceko
├── de.json # Terjemahan bahasa Jerman
└── ... # Total 30 file lokal
scripts/
├── i18n/
│ ├── generate-multilang.mjs # Mesin terjemahan otomatis (Google Translate, 888 baris)
│ ├── generate-qa-checklist.mjs # QA analisis statis
│ ├── run-visual-qa.mjs # QA visual Playwright
│ └── untranslatable-keys.json # Daftar yang diizinkan untuk validasi (236 kunci)
├── validate_translation.py # Validator terjemahan
├── check_translations.py # Pemeriksa kunci kode ke JSON
└── i18n_autotranslate.py # Penerjemah dokumentasi berbasis LLM
.github/workflows/
└── ci.yml # Validasi i18n dalam matriks CI
docs/
├── I18N.md # File ini — dokumentasi toolchain i18n
├── i18n/
│ ├── README.md # Indeks bahasa yang dibuat otomatis
│ ├── cs/ # Dokumentasi bahasa Ceko
│ │ └── docs/
│ │ ├── I18N.md # Terjemahan bahasa Ceko dari file ini
│ │ └── ...
│ ├── de/ # Dokumentasi bahasa Jerman
│ └── ... # 30 direktori lokal
└── reports/
├── i18n-qa-checklist-*.md # Laporan analisis statis
└── i18n-visual-qa-*.md # Laporan QA visual
Praktik Terbaik
Saat Mengedit Terjemahan
- Selalu edit
en.jsonterlebih dahulu — itulah sumber kebenaran - Jalankan
generate-multilang.mjs messagesuntuk menyebarkan kunci baru ke semua lokal - Tinjau terjemahan otomatis — Google Translate hanyalah titik awal, bukan hasil akhir
- Validasi sebelum melakukan commit —
python3 scripts/validate_translation.py quick -l <lang> - Perbarui
untranslatable-keys.jsonjika sebuah kunci harus tetap dalam bahasa Inggris
Keamanan Placeholder
- Placeholder ICU (
{count},{value},{total},{seconds}) harus dipertahankan persis sama - Format jamak (
{count, plural, one {# model} other {# models}}) harus mempertahankan strukturnya - Validator mendeteksi ketidaksesuaian placeholder secara otomatis
Menambahkan Kunci Terjemahan Baru dalam Kode
// Use namespaced keys
const t = useTranslations("settings");
t("cacheSettings"); // maps to settings.cacheSettings in JSON
// Run check_translations.py to verify keys exist
python3 scripts/check_translations.py --verbose
Pertimbangan RTL
- Bahasa Arab (
ar) dan Ibrani (he) adalah lokal RTL - Hindari
left/rightCSS yang dikodekan keras — gunakan properti logisstart/end - QA visual menangkap ketidaksesuaian tata letak RTL melalui
run-visual-qa.mjs
Masalah yang Diketahui & Riwayat
Perbaikan in.json → hi.json
Generator awalnya menggunakan code: "in" (kode Google Translate yang sudah usang) untuk bahasa Hindi, bukan ISO 639-1 yang benar yaitu hi. Hal ini menciptakan duplikat in.json yang tidak terhubung dari hi.json. Diperbaiki dengan mengubah code: "in" menjadi code: "hi" di generate-multilang.mjs dan menghapus file yang tidak terhubung tersebut.
docs/i18n/README.md Dibuat Secara Otomatis
File docs/i18n/README.md sepenuhnya dihasilkan ulang oleh generate-multilang.mjs docs. Setiap pengeditan manual akan hilang. Gunakan docs/guides/I18N.md (file ini) untuk dokumentasi yang ditulis tangan yang harus tetap ada.
Daftar Kunci yang Tidak Dapat Diterjemahkan Eksternal
Daftar yang diizinkan untranslatable-keys.json dipindahkan dari set Python inline di validate_translation.py ke file JSON eksternal agar lebih mudah dipelihara. Validator memuatnya saat runtime.
Perbaikan Kode Hindi di generate-multilang.mjs
Generator awalnya menggunakan code: "in" (kode Google Translate yang sudah usang) untuk bahasa Hindi, bukan ISO 639-1 yang benar yaitu hi. Ini diperkenalkan dalam commit upstream 952b0b22c oleh diegosouzapw. Diperbaiki dengan mengubah code: "in" menjadi code: "hi" di array LOCALE_SPECS dan menghapus file in.json yang tidak terhubung.
Keluaran Jumlah Kunci yang Diabaikan di validate_translation.py
Pemeriksaan quick kini menampilkan jumlah kunci yang diabaikan dari untranslatable-keys.json:
Missing: 0
Untranslated: 0
Ignored (UNTRANSLATABLE_KEYS): 236