Pemecahan masalah
Setiap entri di sini adalah kegagalan yang benar-benar pernah dialami seseorang. Masing-masing mencantumkan gejala, penyebab terjadinya, dan solusinya — sebagian besar berasal dari satu di antara tiga hal: frasa tidak ada di proyek, SDK tidak pernah diinisialisasi, atau placeholder ditulis untuk konteks yang salah.
Tidak ada yang diterjemahkan — setiap frasa tetap dalam bahasa sumber
Jika semuanya menampilkan teks sumber, hampir pasti SDK gagal diinisialisasi. SDK sengaja dirancang gagal secara lunak (UI Anda tidak boleh rusak), sehingga satu-satunya sinyal yang jelas ada di konsol browser — periksa di sana lebih dulu. Penyebab yang umum, berdasarkan kemungkinan terbesar:
- CORS. Permintaan pertama SDK adalah
authorize-project; jika API Anda tidak memasukkan origin aplikasi ke dalam allowlist, browser akan memblokirnya dan init gagal di titik itu juga. Ingat bahwa origin adalah skema + host + port yang persis sama —localhost:5173danlocalhost:5174adalah origin yang berbeda, dan server pengembangan sering berpindah port ketika port biasanya sudah terpakai. Masukkan setiap port yang benar-benar Anda gunakan untuk pengembangan ke dalam allowlist. - Kredensial salah. Project id / API key yang hilang atau salah ketik akan membuat panggilan authorize yang sama gagal. Konsol menampilkan permintaan dan URL yang gagal.
- Anda sedang melihat locale dasar. Di locale dasar, "terjemahan" adalah teks sumber — tidak ada perubahan yang terlihat. Beralihlah ke locale target untuk menguji.
# The SDK's first call is an authorize-project request.
# If the browser blocks it, NOTHING translates. Check the console for:
Access to fetch at 'https://your-api/api/authorize-project/...'
from origin 'http://localhost:5173' has been blocked by CORS policy
# Fix: allowlist the app's EXACT origin (scheme + host + port) on the API.
CORS_ALLOWED_ORIGINS=http://localhost:5173,https://app.example.com Satu frasa tidak mau diterjemahkan (tetapi yang lain bisa)
Frasa dalam kode Anda adalah kunci pencarian — frasa adalah kuncinya. Jika satu frasa tampil sebagai teks sumber sementara frasa di sekitarnya diterjemahkan, berarti kunci itu tidak ada di katalog proyek:
- Frasa itu tidak pernah terdaftar. Pendaftaran terjadi melalui penemuan token, dan hanya kunci tulis yang dapat melakukannya. Jika frasa tersebut dibuat saat aplikasi berjalan dengan kunci hanya-baca, frasa itu tidak pernah dikirim ke mana pun — jalankan layar tersebut sekali di lingkungan pengembangan dengan kunci tulis, atau tambahkan frasa di dasbor.
- Teksnya berubah. Perubahan apa pun — satu kata, tanda baca, bahkan spasi kosong — menjadikannya frasa baru yang belum memiliki terjemahan. Terjemahan lama masih ada di bawah kunci lama. Hal ini terutama berpengaruh pada blok konten: blok
<Translate>ditokenisasi dari markup-nya, sehingga mengubah teks atau struktur blok akan mengubah apa yang dicari, dan blok tersebut diam-diam kembali ke teks sumber sampai bentuk barunya didaftarkan dan diterjemahkan. - Terjemahan mesin belum tersedia. Frasa yang baru didaftarkan bisa tertinggal sesaat dari terjemahannya, dan locale di luar daftar target proyek tidak akan pernah mendapatkannya. Periksa frasa tersebut di dasbor: sudah terdaftar? sudah diterjemahkan ke locale ini?
Mengapa frasa yang hilang tidak memicu error?
Memang disengaja. Di produksi, sistem terjemahan harus turun ke teks sumber yang tetap terbaca, bukan ke halaman yang rusak — jadi frasa yang belum terdaftar menampilkan teks sumbernya dan SDK tetap diam. Sisi sebaliknya: pada kunci hanya-baca, frasa yang hilang bersifat senyap. Tidak ada yang dicatat, tidak ada yang didaftarkan, dan Anda baru tahu saat pengguna melihat teks bahasa Inggris. Disiplin yang mencegahnya adalah pemisahan kunci — kembangkan dengan kunci tulis agar setiap frasa yang dirender UI Anda ditemukan, lalu rilis dengan kunci hanya-baca.
# Development — write key: new phrases are discovered,
# registered, and machine-translated as you build.
VITE_LANGSYS_API_KEY=write-key
# Production — read-only key: fetches the finished catalog only.
# Unregistered phrases silently render their source text.
VITE_LANGSYS_API_KEY=read-only-key Placeholder saya tampil apa adanya — "Hi %name%" atau "Hi {name}"
- Pada pemanggilan
t(), placeholder menggunakan kurung kurawal tunggal{name}, dan interpolasi hanya berjalan jika Anda meneruskan parameternya:t('Hello, {name}!', 'Greetings', { name }). - Dalam markup
<Translate>/<Phrase>di React, Vue, atau Svelte, tulis placeholder sebagai%name%. Compiler framework akan memproses{name}polos sebagai ekspresi sebelum SDK sempat melihatnya;%name%lolos dari kompilasi dan SDK menormalkannya kembali menjadi{name}saat penangkapan.{name}biasa tidak masalah di HTML murni, karena tidak ada sintaks templat yang bentrok. - Params tidak ada? Jika tidak ada
paramsyang diberikan, templat dirender apa adanya — itulah%name%harfiah yang Anda lihat.
Awalnya berfungsi, lalu rusak setelah saya berganti locale bolak-balik
Perbarui SDK. Bug nyata yang sudah diperbaiki di area ini: kembali ke locale awal/SSR membuat katalog sebelumnya tetap aktif (diperbaiki di langsys-js-typescript 0.2.2), dan konsumen Translate/Phrase content-block bisa menggantung selamanya pada katalog yang diisi dari server (diperbaiki di 0.2.3). Jika Anda melihat string locale lama atau blok yang tidak pernah selesai dimuat, periksa versi yang terpasang dengan changelog SDK dasar sebelum men-debug kode Anda sendiri.
Sisi server: halaman mengalami error 500 alih-alih turun kualitas secara bertahap
Klien SDK PHP melempar error jika dibuat tanpa kredensial — sehingga aplikasi Laravel (atau PHP biasa) dengan LANGSYS_API_KEY kosong akan gagal pada resolusi container, sebelum terjemahan apa pun berjalan. Setel kredensialnya (atau, untuk aplikasi yang harus bisa boot tanpa kredensial, ikat klien pengganti seperti yang dilakukan aplikasi demo). Setelah kredensial tersedia, kegagalan API saat runtime akan ditangani dengan degradasi halus: API yang tidak dapat dijangkau atau menolak permintaan akan menampilkan teks sumber dan melaporkan pengecualiannya — halaman tidak pernah ikut mati.
Sisi server: permintaan pertama menggantung, lalu semuanya cepat
Batas waktu HTTP SDK PHP adalah 30 detik, dan instance API yang bangun dari kondisi idle bisa mendekati batas itu pada panggilan pertama. Permintaan tersebut akan selesai dengan lambat (dan memanaskan cache katalog — semua permintaan setelahnya dilayani dari cache) atau mengalami timeout dan menampilkan teks sumber. Jika pemuatan halaman pertama Anda setelah jeda cukup lama terasa lambat, inilah penyebabnya; itu karena API sedang memanas, bukan masalah pada integrasi Anda.
Sisi server: saya merender dengan write key tetapi frasanya tidak muncul di dasbor
Frasa yang ditemukan diantrekan selama permintaan berlangsung dan dikirim setelah respons dikirim — middleware terminable milik Laravel. Segarkan dasbor sesaat setelah halaman dimuat, bukan saat sedang dimuat. Pada runtime worker yang berjalan lama (Octane, FrankenPHP, RoadRunner), pastikan Anda memakai integrasi bawaan SDK — hook shutdown PHP biasa tidak pernah dijalankan di antara permintaan worker.
Rendering server: terjemahan dari satu permintaan bocor ke permintaan lain
SDK dasar JS menyimpan katalog satu locale pada satu waktu — ini adalah singleton tingkat modul. Server Node yang merender locale berbeda untuk permintaan bersamaan akan mengalami race condition. Ambil katalog per permintaan dan isi klien dari katalog tersebut, seperti pola dalam panduan Next.js, Nuxt, dan SvelteKit, atau jalankan satu locale per proses.
Masih buntu? Buka issue di repo SDK — typescript, react, vue, svelte, php, atau laravel — beserta output konsol (atau log server) dari permintaan yang gagal. Atau kirim email ke [email protected].