Di 20 Filters Money, Metafield, Cart, Customer, dan Localization > Filter Terjemahan: t kita udah kenal filter t dari sisi pemakainya. Sekarang kita ke sisi penyedianya: folder locales, dua jenis file di dalamnya, dan aturan-aturan yang bikin theme kamu bisa dipakai merchant di negara manapun.

Locale file itu file JSON berisi kumpulan terjemahan buat semua teks di theme dan di theme editor. Dua manfaatnya:

  1. Merchant punya satu tempat buat ngedit kata dan frasa yang berulang di theme (“Add to cart” muncul di puluhan tempat, tapi diedit sekali).
  2. Konten storefront dan setting theme editor bisa diterjemahin ke banyak bahasa buat merchant dan pembeli internasional.

Prinsipnya: theme yang baik gak punya teks hardcode. Semua teks yang dilihat pembeli lewat locale file.

Lokasi dan Dua Jenis File

└── theme
  ...
  ├── config
  └── locales
    ├── en.default.json
    ├── en.default.schema.json
    ├── es-ES.json
    ├── es-ES.schema.json
    ...
  1. Storefront locale file (.json), terjemahan buat konten storefront yang dilihat pembeli. Merchant bisa ngeditnya lewat Shopify Language Editor di admin.
  2. Schema locale file (.schema.json), terjemahan buat setting theme editor (label, info, nama section) yang dilihat merchant.

Dua-duanya punya struktur dan aturan penamaan yang sama, bedanya cuma siapa yang baca dan cara ngerujuknya.

Struktur Isi

Tiga tingkat:

  1. Category, kategori level atas.
  2. Group, pengelompokan kedua di dalam kategori.
  3. Description, tingkat ketiga, terjemahan individualnya.
{
  "my_category": {
    "my_group": {
      "my_description": "translation text",
      ...
    },
    ...
  },
  ...
}

Tips penamaan: bikin deskripsi yang cukup deskriptif buat ngasih konteks. blogs.article_comment.submit_button_text lebih jelas dari blogs.article_comment.submit, karena penerjemah (yang mungkin gak lihat theme-nya) langsung tau ini teks tombol.

Penamaan File

Ngikutin standar IETF language tag: kode bahasa huruf kecil, opsional diikuti kode wilayah huruf besar:

  1. English, Great Britain: en-GB.json dan en-GB.schema.json.
  2. Spanish, Spain: es-ES.json dan es-ES.schema.json.
  3. French, Canada: fr-CA.json dan fr-CA.schema.json.

Kalau bahasanya gak spesifik wilayah, cukup dua huruf: Finnish semua wilayah fi.json dan fi.schema.json. Buat Indonesia: id.json dan id.schema.json.

1. Default Locale File

Kamu wajib nentuin satu file default per jenis, dengan format *.default.json dan *.default.schema.json. File ini berisi terjemahan buat bahasa default theme, dan cuma boleh satu default per jenis. Kebanyakan theme pakai en.default.json dan en.default.schema.json.

Kenapa penting? Kalau kunci terjemahan gak ada di file bahasa aktif, Shopify fallback ke file default. Jadi file default harus lengkap, file bahasa lain boleh sebagian.

❌ salah, dua default

locales/en.default.json
locales/id.default.json

✅ benar, satu default, sisanya biasa

locales/en.default.json
locales/id.json

Batasan

  1. Maksimal 3400 terjemahan per locale file.
  2. Nilai terjemahan maksimal 1000 karakter.

Storefront Locale Files

File .json buat teks yang dilihat pembeli. Layout, template, snippet, section, block, dan aset Liquid ngerujuknya pakai filter t (nama aslinya translate), yang ngembaliin string sesuai bahasa aktif toko.

Catatan: pesan checkout dan sistem (error login, notifikasi pesanan) juga bisa diterjemahin merchant lewat Language Editor, tapi datanya disimpan Shopify di luar locale file theme.

1. Susunan Kunci yang Disarankan

Biar terjemahan gampang dipetakan dan merchant gak bingung di Language Editor, susun kuncinya ngikutin struktur theme. Dua tingkat pertama yang umum:

  1. general: 404, breadcrumbs, search (halaman hasil dan blank slate), pagination.
  2. blogs: article, komentar artikel, sidebar blog.
  3. cart: isi keranjang, update, catatan, link ke checkout.
  4. collection: koleksi, loop koleksi.
  5. products: produk, loop produk, produk terkait.
  6. layout: judul field umum dan identifier.
  7. customer: akun, pesanan (daftar dan detail), aktivasi akun, alamat, login, password, registrasi.
  8. contact: form kontak, error form.
  9. home_page: blank slate, featured, help.
  10. gift_cards: judul, syarat pemakaian.

Kalau terjemahannya dipakai di snippet, kelompokkan sesuai kategori yang paling dekat sama peran snippet-nya: snippet related-products.liquid → grup products.

2. Ngerujuk Terjemahan

Tiga file bahasa:

{
  "blog": {
    "comment": {
      "email": "Your email"
    }
  }
}
{
  "blog": {
    "comment": {
      "email": "Votre adresse courriel"
    }
  }
}
{
  "blog": {
    "comment": {
      "email": "Su correo electrónico"
    }
  }
}

Dirujuk pakai kunci bertitik dalam kutip tunggal:

{{ 'blog.comment.email'  | t }}

Hasilnya Your email, Votre adresse courriel, atau Su correo electrónico tergantung bahasa aktif.

3. Interpolasi, Pluralisasi, dan _html

Tiga fitur t yang udah dibahas lengkap di 20 Filters Money, Metafield, Cart, Customer, dan Localization > Filter Terjemahan: t, ini ringkasannya dari sisi file locale:

  1. Interpolasi: tulis {{ name }} di string, kirim t: name: customer.first_name (boleh banyak, dipisah koma). Penerjemah bebas naruh variabelnya di posisi manapun.
{
  "layout": {
    "header": {
      "hello_user": "Hello {{ first_name }} {{ last_name }}!"
    }
  }
}
  1. Pluralisasi: bikin object dengan kunci CLDR zero, one, two, few, many, other, kirim t: count: n. Tiap bahasa cuma butuh kunci yang relevan (Inggris one dan other, Indonesia cukup other).
{
  "customers": {
    "orders": {
      "order_count": {
        "one": "You've made {{ count }} order with us",
        "other": "You've made {{ count }} orders with us"
      }
    }
  }
}
  1. _html: terjemahan di-escape bawaannya, jadi HTML tampil sebagai teks. Akhiri kunci deskripsi dengan _html biar HTML-nya dirender. Berguna juga buat terjemahan yang dipakai di <script> atau aset .js.liquid.
{
  "layout": {
    "header": {
      "announcement_bar_text_html": "Spend $50 and get <strong>FREE</strong> shipping"
    }
  }
}

4. Tanggal dan Waktu: date_formats

Filter date dan time_tag punya format bawaan bernama yang tampil sesuai bahasa aktif:

{{ order.created_at | date: format: 'abbreviated_date' }}

Hasilnya Dec 31, 2018 di Inggris, 31 déc. 2018 di Prancis. Format bawaannya ada di 18 Filters String, Math, dan Array > date.

Kamu bisa nambahin format kustom lewat object date_formats di locale file, pakai parameter strftime Ruby:

{
  "date_formats": {
    "month_and_year": "%B %Y"
  }
}
{{ order.created_at | date: format: 'month_and_year' }}

Hasilnya December 2018. Daftar parameter strftime ada di dokumentasi Ruby atau strfti.me.

Hati-hati: format kustom harus ada di semua locale file. Kalau bahasa aktif gak punya format itu, Shopify ngerender error Liquid di halaman.

❌ format cuma di en.default.json, pengunjung Prancis lihat error

locales/en.default.json → "date_formats": { "month_and_year": "%B %Y" }
locales/fr.json → (gak ada date_formats)

✅ ada di semua file

locales/en.default.json → "date_formats": { "month_and_year": "%B %Y" }
locales/fr.json → "date_formats": { "month_and_year": "%B %Y" }

5. Bahasa Checkout dan Pesan Sistem

Shopify nyediain sendiri terjemahan checkout dan pesan sistem buat bahasa: Bulgaria, China (Sederhana), China (Tradisional), Kroasia, Ceko, Denmark, Belanda, Inggris, Finlandia, Prancis, Jerman, Yunani, Hindi, Hungaria, Indonesia, Italia, Jepang, Korea, Lituania, Melayu, Norwegia (Bokmål), Polandia, Portugis (Brasil), Portugis (Portugal), Rumania, Rusia, Slovakia, Slovenia, Spanyol, Swedia, Thailand, Turki.

Kalau toko pakai bahasa di luar daftar, merchant harus ngisi manual terjemahan checkout dan pesan sistem lewat Language Editor. Indonesia udah ada, jadi aman.

Schema Locale Files

File .schema.json buat teks yang dilihat merchant di theme editor: label setting, nama section, teks header. Tujuannya biar theme editor tampil dalam bahasa aktif toko.

1. Atribut yang Bisa Diterjemahin

Bukan semua atribut schema, cuma ini:

  1. Semua setting: info, label.
  2. settings_schema.json, section schema, block: name.
  3. select: group.
  4. html, number, text, textarea, video_url: placeholder.
  5. range: unit.
  6. header, paragraph: content.
  7. presets: name, category.
  8. html, inline_richtext, liquid, richtext, text, textarea, url, video, video_url: default.

Poin 8 menarik: default setting teks bisa diterjemahin. Jadi teks awal “Welcome to our store” bisa jadi “Selamat datang di toko kami” buat toko berbahasa Indonesia, sebelum merchant nyentuh apa-apa.

2. Cara Ngerujuk: Prefix t:

Beda sama storefront yang pakai filter t di Liquid, schema itu JSON, gak bisa pakai filter. Jadi rujukannya pakai string berawalan t::

t:translation_category.translation_group.translation_name

Contoh nerjemahin name section produk:

{
  "sections": {
    "product": {
      "name": "Product"
    }
  }
}
{% schema %}
{
  "name": "t:sections.product.name",
  ...
}
{% endschema %}

Ini yang kamu lihat di contoh color_scheme_group di 30 Settings dan Input Settings > 4. color_scheme_group: "label": "t:settings_schema.colors.settings.background.label". Theme Dawn dan Horizon nerjemahin semua label schema-nya begini.

❌ label hardcode, theme editor selalu Inggris

{ "type": "checkbox", "id": "show_vendor", "label": "Show vendor" }

✅ label dari schema locale

{ "type": "checkbox", "id": "show_vendor", "label": "t:sections.product.settings.show_vendor.label" }

Konvensi kunci yang umum: sections.<nama_section>.settings.<id_setting>.label, sections.<nama_section>.blocks.<tipe_block>.name, sections.<nama_section>.presets.name, dan settings_schema.<kategori>.settings.<id>.label buat theme setting.

Dua Dunia, Jangan Ketuker

Ini sumber kebingungan paling umum:

  1. Storefront (en.default.json): dibaca lewat filter t di Liquid ({{ 'products.product.add_to_cart' | t }}), dilihat pembeli, diedit merchant lewat Language Editor.
  2. Schema (en.default.schema.json): dibaca lewat prefix t: di JSON schema ("label": "t:sections.product.name"), dilihat merchant di theme editor.

Dan ada yang ketiga: object locales di dalam {% schema %} section dari 26 Sections dan Section Schema > 13. locales, yang dibaca pakai filter t tapi cuma tersedia buat section itu. Cocok buat section mandiri yang mau dibagi ke banyak theme, tapi teks yang dipakai di banyak tempat tetap taruh di folder locales/.

Nambahin Bahasa Baru

Alurnya kalau mau nambahin Indonesia ke theme yang cuma punya Inggris:

  1. Salin en.default.json jadi id.json, terjemahin nilainya (kunci jangan diubah).
  2. Salin en.default.schema.json jadi id.schema.json, terjemahin.
  3. Pastiin date_formats kustom (kalau ada) ikut disalin.
  4. Merchant ngaktifin bahasa Indonesia di admin (Settings > Languages), dan waktu pengunjung pilih Indonesia, t otomatis baca id.json.

Kunci yang gak kamu terjemahin di id.json bakal fallback ke en.default.json, jadi terjemahan sebagian gak bikin error, cuma campur bahasa. Theme Check punya aturan MatchingTranslations yang ngecek kunci di tiap file bahasa cocok sama file default, dibahas di 67 Theme Check Referensi Aturan M–V.

Ringkasan

  1. Locale file itu JSON terjemahan di folder locales, biar teks gampang diedit merchant dan bisa diterjemahin.
  2. Dua jenis: storefront (.json, buat pembeli, dibaca filter t) dan schema (.schema.json, buat merchant di theme editor, dibaca prefix t:).
  3. Struktur tiga tingkat: kategori → grup → deskripsi, dengan nama deskripsi yang ngasih konteks.
  4. Penamaan IETF: en-GB.json, fi.json, dan tepat satu file default per jenis (*.default.json, *.default.schema.json) yang harus lengkap karena jadi fallback.
  5. Batas: 3400 terjemahan per file, 1000 karakter per nilai.
  6. Susun kunci storefront ngikutin struktur theme (general, blogs, cart, collection, products, layout, customer, contact, home_page, gift_cards).
  7. Fitur t: interpolasi {{ var }}, pluralisasi CLDR dengan count, sufiks _html biar gak di-escape.
  8. date_formats nambahin format tanggal kustom (strftime), wajib ada di semua locale file kalau gak mau error.
  9. Checkout dan pesan sistem diterjemahin Shopify buat 32 bahasa termasuk Indonesia, di luar itu manual lewat Language Editor.
  10. Atribut schema yang bisa diterjemahin: label, info, name, group, placeholder, unit, content, name/category preset, dan default setting teks.
  11. Jangan ketuker tiga dunia: t filter (storefront), t: prefix (schema), dan locales di schema section (lokal buat section itu).

Bab selanjutnya kita bahas satu file yang udah pensiun tapi masih sering ditemuin di theme lama: checkout.liquid, kenapa dia dihapus, apa penggantinya (Checkout Extensibility), dan apa yang harus kamu lakuin kalau nemu theme yang masih makainya.