Apa itu i18n & l10n? — i18n

Pernah pake aplikasi yang tampilan-nya cuma bahasa Inggris padahal target user-nya Indonesia? Atau lihat tanggal "04/16/2026" yang bikin bingung — ini April…

Internationalization, disingkat i18n, adalah menyiapkan kode supaya aplikasinya bisa dipakai dalam bahasa dan kebiasaan daerah mana pun tanpa kodenya diubah. Localization, disingkat l10n, adalah mengisi satu bahasa dan daerah itu: terjemahan, format harga, format tanggal. Bayangin Bu Sri menyiapkan Homestay Kabut di Dieng untuk tamu dari luar negeri. Memasang colokan universal di tiap kamar adalah i18n: dikerjakan sekali, waktu membangun. Menaruh adaptor, buku panduan berbahasa Jepang, dan jam dinding yang benar untuk tamu dari Jepang adalah l10n: dikerjakan per tamu, tanpa membongkar dinding.

🧪 Tebakan cepat: Kartu pesan Kamar Teras di halaman Bu Sri berisi judul, harga, tanggal check-in, tiga tombol lama menginap, total, tombol pesan, dan satu catatan. Dari semua teks di kartu itu, berapa yang cukup diterjemahkan kata per kata untuk tamu dari Jepang: hampir semua, sekitar separuh, atau kurang dari separuh? Jawabannya ada di bagian "Menghitung teks hard-coded di halaman Bu Sri".

i18n, l10n, g11n, dan translation

Empat istilah ini sering tertukar. Angka di tengah singkatannya cuma jumlah huruf: i, 18 huruf, n adalah internationalization; l, 10 huruf, n adalah localization; g, 11 huruf, n adalah globalization.

Istilah Artinya Di halaman Bu Sri
Translation Mengganti kata ke bahasa lain "Pesan kamar" jadi "予約する"
l10n (localization) Menyesuaikan halaman untuk satu locale: terjemahan, plus format uang, tanggal, jumlah, dan arah tulisan Untuk tamu Jepang: harga IDR 700,000, tanggal 12月12日, "2泊"
i18n (internationalization) Menyiapkan arsitektur kode supaya l10n bisa dikerjakan tanpa mengubah kode Teks pindah ke kamus per bahasa, angka dan tanggal lewat Intl, file disimpan UTF-8, CSS memakai logical properties
g11n (globalization) Keputusan dan kerja untuk melayani pasar lain, termasuk i18n dan l10n Bu Sri memutuskan menerima tamu dari Jepang dan Mesir, termasuk cara bayar dan jam balas chat

Locale: kode bahasa, aksara, dan wilayah

Locale adalah kode yang menyebut bahasa dan kebiasaan daerah yang dipakai. Web memakai format BCP 47, disebut juga language tag: bagian-bagian yang disambung tanda minus.

Tag Bahasa Aksara Wilayah Contoh pemakaian
id-ID id Indonesia ID Indonesia Halaman asli Bu Sri
ja-JP ja Jepang JP Jepang Tamu dari Jepang
zh-Hant-TW zh Tionghoa Hant Han tradisional TW Taiwan Tag dengan tiga bagian
sr-Latn sr Serbia Latn Latin Bahasa Serbia yang ditulis huruf Latin
es-419 es Spanyol 419 Amerika Latin Wilayah boleh berupa kode angka
new Intl.Locale('ja').maximize().toString();    // "ja-Jpan-JP"
new Intl.Locale('ar').maximize().toString();    // "ar-Arab-EG"
new Intl.Locale('sr').maximize().toString();    // "sr-Cyrl-RS": tanpa Latn, bahasa Serbia ditulis huruf Kiril
new Intl.Locale('zh-TW').maximize().toString(); // "zh-Hant-TW"
Intl.getCanonicalLocales('ID-id');              // ["id-ID"]: huruf besar dan kecilnya dirapikan

Hasilnya sama di Chromium 147, Firefox 146, WebKit 26.4 (mesin Safari), dan Node 22.22.1.

Empat locale untuk Homestay Kabut

Track ini membawa halaman Bu Sri ke empat locale. Tiap locale dipilih karena menguji hal yang berbeda:

Kenapa ar-EG, bukan ar-SA? Wilayah mengubah hasil. Untuk ar-SA, Safari 26.4 memakai kalender Hijriah dan menulis 12 Desember 2026 sebagai ٣ رجب ١٤٤٨ هـ, sementara Chrome dan Firefox memakai kalender Masehi. Untuk ar-EG, ketiganya memakai kalender Masehi.

Kartu yang sama di empat locale, diformat Intl di Chromium 147 (harga dengan maximumFractionDigits: 0, tanggal dengan dateStyle: 'medium', timeStyle: 'short', dan timeZone: 'Asia/Jakarta'):

id-ID en-US ja-JP ar-EG
Total 2 malam Rp 700.000 IDR 700,000 IDR 700,000 ٧٠٠٬٠٠٠ IDR
Check-in 12 Des 2026, 14.00 Dec 12, 2026, 2:00 PM 2026/12/12 14:00 ١٢/١٢/٢٠٢٦، ٢:٠٠ م
Kategori jamak untuk 2 other other other two
Tombol 2 malam 2 malam 2 nights 2泊 ليلتان
Arah tulisan kiri ke kanan kiri ke kanan kiri ke kanan kanan ke kiri

Kata di tombol berasal dari kamus terjemahan; Intl.PluralRules cuma memberi tahu kategori mana yang dipakai. Bahasa Arab punya bentuk khusus untuk tepat dua (dual): ليلتان artinya "dua malam".

Yang berubah selain kata

Aspek Contoh di halaman Bu Sri
Angka dan uang Pemisah ribuan titik di id-ID, koma di en-US dan ja-JP, dan ٬ dengan angka ٠ sampai ٩ di ar-EG. "Rp" di depan angka untuk id-ID, "IDR" di belakang untuk ar-EG.
Tanggal dan jam "Sabtu, 12 Desember 2026 pukul 14.00" di id-ID, "Saturday, December 12, 2026 at 2:00 PM" di en-US, "2026年12月12日土曜日 14:00" di ja-JP.
Jumlah 2 malam, 2 nights, 2泊, ليلتان: bentuk katanya ikut jumlah.
Arah Bahasa Arab ditulis kanan ke kiri, jadi garis hijau di awal kartu pindah ke kanan.
Urutan abjad ['Zahra', 'Ömer', 'andi'].sort() memberi ["Zahra", "andi", "Ömer"]. Bahasa Swedia memang menaruh Ö sesudah Z, bahasa Jerman menaruhnya bersama O.
Nama orang Banyak orang Indonesia bernama satu kata, dan nama Jepang ditulis marga dulu (山田 太郎). Kolom wajib "Nama depan" plus "Nama belakang" menyulitkan keduanya.
Alamat Alamat Jepang ditulis dari yang besar ke yang kecil, diawali kode pos 〒; alamat Indonesia punya RT/RW dan kelurahan.
Panjang teks "Pesan kamar, bayar di tempat" dan "Book now, pay at the homestay" beda lebar, seperti yang diukur di pelajaran UI/UX.

Menghitung teks hard-coded di halaman Bu Sri

Hard-coded artinya teksnya ditulis langsung di dalam kode, bukan diambil dari kamus. Ini kartu Bu Sri sebelum di-i18n:

<html lang="id">
<head>
  <title>Kamar Teras · Homestay Kabut</title>
  <style>.card { padding-left: 20px; border-left: 4px solid #15803d; }</style>
</head>
<body>
  <section class="card">
    <h1>Kamar Teras</h1>
    <p>Rp 350.000 / malam</p>
    <p>Check-in 12 Des 2026, 14.00</p>
    <div role="group" aria-label="Lama menginap">
      <button>1 malam</button>
      <button aria-pressed="true">2 malam</button>
      <button>3 malam</button>
    </div>
    <p id="total">Total 2 malam: Rp 700.000</p>
    <button>Pesan kamar, bayar di tempat</button>
    <p>Gratis batal sampai 3 hari sebelum check-in.</p>
  </section>
  <script>
    function pilih(n) {
      document.getElementById('total').textContent =
        'Total ' + n + ' malam: Rp ' + (350000 * n).toLocaleString('id-ID');
    }
  </script>
</body>
</html>

Ada 11 teks yang dibaca atau didengar tamu:

Jenis Teks Jumlah
Cuma kata <title>, judul "Kamar Teras", aria-label "Lama menginap", tombol "Pesan kamar, bayar di tempat" 4
Kata plus angka, uang, tanggal, atau jumlah "Rp 350.000 / malam", "Check-in 12 Des 2026, 14.00", "1 malam", "2 malam", "3 malam", "Total 2 malam: Rp 700.000", "Gratis batal sampai 3 hari sebelum check-in." 7

Cuma 4 dari 11 yang bisa diterjemahkan kata per kata, jadi kurang dari separuh. Itu jawaban tebakannya. Tujuh sisanya butuh Intl atau aturan jamak, karena angka, tanggal, dan bentuk katanya berubah per locale. Lalu ada 3 tempat lagi di luar teks:

Dua yang paling sering terlupa: <title> dan aria-label. Keduanya gak kelihatan di kartu, tapi muncul di tab browser dan dibacakan screen reader.

⚠️ Jebakan yang sering ketemu

TL;DR: i18n (i, 18 huruf, n: internationalization) menyiapkan arsitektur kode supaya bisa multi-bahasa tanpa kodenya diubah; l10n (localization) mengisi satu locale: terjemahan plus format uang, tanggal, jumlah, dan arah tulisan. Translation cuma bagian dari l10n, dan g11n adalah keputusan melayani pasar lain. Locale ditulis BCP 47 dengan tanda minus: bahasa, aksara, wilayah (id-ID, zh-Hant-TW, sr-Latn); id_ID melempar RangeError. Track ini memakai id-ID (sumber), en-US, ja-JP (CJK, tanpa jamak), dan ar-EG (RTL, angka ٠ sampai ٩, enam kategori jamak). Yang berubah bukan cuma kata: angka, uang, tanggal, jamak, arah, urutan abjad, nama, alamat. Kartu Bu Sri punya 11 teks hard-coded, dan cuma 4 yang bisa diterjemahkan kata per kata; ditambah lang, potongan kalimat di script, dan CSS kiri kanan.

Yang akan kamu pelajari