Files
2026-07-13 13:39:12 +08:00

19 KiB
Raw Permalink Blame History

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-intl dengan resolusi lokal berbasis cookie
  • Konfigurasi: src/i18n/config.ts — mendefinisikan semua 30 lokal, nama bahasa, bendera

Alur Runtime

  1. Pengguna memilih bahasa → cookie NEXT_LOCALE disetel
  2. src/i18n/request.ts menyelesaikan lokal: cookie → header Accept-Language → fallback en
  3. Import dinamis memuat messages/{locale}.json
  4. Komponen menggunakan useTranslations("namespace") dan t("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.md dihasilkan ulang setiap kali dijalankan — ini adalah indeks dokumentasi yang dibuat otomatis
  • File README.{code}.md di root hanya dibuat jika belum ada (melewati lokal yang ada di EXISTING_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.json tetapi 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:

  1. Job i18n-matrix — secara dinamis menemukan semua file lokal (tidak termasuk en.json)
  2. Job i18n — menjalankan validate_translation.py quick -l '<lang>' untuk setiap lokal secara paralel
  3. 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

  1. Selalu edit en.json terlebih dahulu — itulah sumber kebenaran
  2. Jalankan generate-multilang.mjs messages untuk menyebarkan kunci baru ke semua lokal
  3. Tinjau terjemahan otomatis — Google Translate hanyalah titik awal, bukan hasil akhir
  4. Validasi sebelum melakukan commitpython3 scripts/validate_translation.py quick -l <lang>
  5. Perbarui untranslatable-keys.json jika 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/right CSS yang dikodekan keras — gunakan properti logis start/end
  • QA visual menangkap ketidaksesuaian tata letak RTL melalui run-visual-qa.mjs

Masalah yang Diketahui & Riwayat

Perbaikan in.jsonhi.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