Gratis update & dukungan instalasi

Tutorial Website 16 Oct 2026

Cara Membuat Website Laravel Multi-bahasa (ID & EN): Panduan Lengkap 2026

R Oleh renz mobellgnd
Cara Membuat Website Laravel Multi-bahasa (ID & EN): Panduan Lengkap 2026

Cara Membuat Website Laravel Multi-bahasa (ID & EN): Panduan Lengkap 2026

Membuat website Laravel multi-bahasa berarti memisahkan seluruh teks antarmuka ke dalam file terjemahan, lalu menyediakan tombol ganti bahasa yang mengubah locale aplikasi lewat middleware dan session. Cara termodern di Laravel 11–13: jalankan php artisan lang:publish, buat file JSON lang/id.json dan lang/en.json, tampilkan teks dengan helper __(), lalu tambahkan middleware yang membaca bahasa pilihan dari session. Totalnya bisa selesai dalam 30 menit.

Panduan ini mengikuti dokumentasi resmi Laravel (laravel.com/docs/localization) dan mencakup hal-hal yang jarang dibahas tutorial lama: JSON translation vs file PHP, pluralisasi, locale via URL, jebakan umum (teks hard-coded), strategi menerjemahkan konten dari database, SEO multibahasa dengan hreflang, sampai alasan kenapa source code dengan fitur multi-bahasa nilainya lebih tinggi di mata pembeli.

Apa itu localization di Laravel?

Localization adalah fitur bawaan Laravel untuk mengambil string teks dalam berbagai bahasa sesuai locale yang aktif. Secara konsep, ada tiga tahap: internationalization (i18n) — merancang aplikasi agar siap menampung banyak bahasa; localization (l10n) — menerjemahkan aplikasi ke bahasa tertentu lewat file terjemahan; dan translation — mengubah teks dari bahasa A ke bahasa B.

Di Laravel modern (versi 11 ke atas), semua terjemahan disimpan di direktori lang/ pada root project. Ada dua gaya penyimpanan:

Gaya Lokasi Contoh pakai Cocok untuk
File PHP per gruplang/id/messages.php__('messages.welcome')Teks yang dikelompokkan (form, menu)
File JSON tunggallang/id.json__('Selamat datang')Teks singkat tersebar di banyak view

Dokumentasi resmi Laravel merekomendasikan JSON untuk aplikasi yang banyak memakai teks inline di Blade. Panduan ini memakai JSON karena paling cepat dipraktikkan — kamu bisa mengganti teks Bahasa Indonesia yang sudah ada di view satu per satu tanpa memecah-mecahnya dulu ke grup file.

Cara ini tidak cocok jika konten website-mu berubah-ubah setiap hari lewat halaman admin (misalnya judul artikel blog). Teks dinamis dari database butuh strategi berbeda — dibahas di bagian akhir artikel.

Bagaimana cara membuat website Laravel multi-bahasa?

Ikuti 6 langkah berikut. Diasumsikan kamu sudah punya project Laravel 11/12/13 yang berjalan.

Langkah 1 — Publish file bahasa

Di Laravel 11 ke atas, folder lang/ tidak disertakan secara default pada skeleton baru. Publish dulu:

php artisan lang:publish

Perintah ini membuat direktori lang/ berisi en/ (file bawaan Laravel: auth.php, pagination.php, passwords.php, validation.php). Kita akan menambah bahasa Indonesia dan file JSON.

Langkah 2 — Buat file terjemahan JSON

Buat dua file: lang/id.json dan lang/en.json. Isinya key-value, di mana key ditulis dalam bahasa default (Indonesia):

// lang/id.json
{
"Selamat datang di website kami": "Selamat datang di website kami",
"Beranda": "Beranda",
"Tentang Kami": "Tentang Kami",
"Kontak": "Kontak",
"Masuk": "Masuk",
"Daftar": "Daftar"
}
// lang/en.json
{
"Selamat datang di website kami": "Welcome to our website",
"Beranda": "Home",
"Tentang Kami": "About Us",
"Kontak": "Contact",
"Masuk": "Sign In",
"Daftar": "Sign Up"
}

Trik ini elegan: key-nya adalah teks Indonesia asli, sehingga view tetap bisa dibaca natural tanpa key abstrak seperti messages.home.

Langkah 3 — Ganti teks di Blade dengan helper __()

Cari semua teks hard-coded di view, lalu bungkus dengan helper __():

<h1>{{ __('Selamat datang di website kami') }}</h1>

<nav>
<a href="/">{{ __('Beranda') }}</a>
<a href="/tentang">{{ __('Tentang Kami') }}</a>
<a href="/kontak">{{ __('Kontak') }}</a>
</nav>

Kalau sebuah key belum ada di file JSON bahasa yang aktif, Laravel otomatis menampilkan key itu sendiri — jadi halaman tidak akan blank, hanya tetap berbahasa Indonesia. Ini perilaku aman saat kamu menerjemahkan bertahap.

Langkah 4 — Buat middleware untuk membaca bahasa pilihan

Locale default disimpan di config/app.php ('locale' => 'en'). Ubah default ke id jika target utama pengunjungmu orang Indonesia, atau biarkan dan kelola per-request lewat middleware:

// app/Http/Middleware/SetLocale.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;

class SetLocale
{
public function handle(Request $request, Closure $next)
{
if ($request->session()->has('locale')) {
App::setLocale($request->session()->get('locale'));
}

return $next($request);
}
}

Daftarkan middleware ini ke grup web di bootstrap/app.php (Laravel 11+):

->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
\App\Http\Middleware\SetLocale::class,
]);
})

Langkah 5 — Buat route dan tombol ganti bahasa

Tambahkan route sederhana untuk menyimpan pilihan bahasa ke session:

// routes/web.php
use Illuminate\Support\Facades\Route;

Route::get('lang/{locale}', function ($locale) {
if (in_array($locale, ['id', 'en'])) {
session(['locale' => $locale]);
}

return redirect()->back();
})->name('lang.switch');

Lalu pasang tombolnya di layout, misalnya di navbar:

<a href="{{ route('lang.switch', 'id') }}"
class="{{ app()->getLocale() == 'id' ? 'font-bold' : '' }}">ID</a>
|
<a href="{{ route('lang.switch', 'en') }}"
class="{{ app()->getLocale() == 'en' ? 'font-bold' : '' }}">EN</a>

Validasi in_array pada route di atas penting: tanpa itu, pengunjung bisa menginjeksi locale sembarangan lewat URL. Detail kecil, tapi inilah bedanya tutorial asal jalan dengan tutorial yang aman dipasang di source code yang dijual ke pembeli.

Langkah 6 — Uji dan rapikan

  1. Jalankan php artisan serve, buka halaman utama.
  2. Klik EN — semua teks berbungkus __() harus berubah ke Inggris.
  3. Klik ID — kembali ke Indonesia.
  4. Cari teks yang belum berubah: itu teks hard-coded yang terlewat. Bungkus satu per satu.

Untuk teks dengan angka, Laravel punya fitur pluralisasi bawaan. Contoh di file JSON:

{
"Ada :count produk": "Ada :count produk|Ada :count produk"
}

Versi Inggrisnya:

{
"Ada :count produk": "There is :count product|There are :count products"
}

Lalu panggil dengan:

{{ trans_choice('Ada :count produk', $total, ['count' => $total]) }}

Bagaimana kalau kontennya dari database (judul artikel, deskripsi produk)?

File lang/ hanya menangani teks statis antarmuka (tombol, menu, label form). Konten dinamis seperti judul artikel atau deskripsi produk yang disimpan di database tidak bisa diterjemahkan dengan __().

Ada tiga pendekatan, dari yang paling sederhana:

  1. Kolom ganda — tambah kolom title_id dan title_en di tabel. Praktis untuk 2 bahasa, tapi berantakan kalau nanti jadi 5 bahasa.
  2. Tabel terjemahan terpisah — tabel product_translations dengan kolom product_id, locale, title, description. Lebih rapi, tapi butuh relasi dan query tambahan.
  3. Package spatie/laravel-translatable — menyimpan terjemahan sebagai JSON dalam satu kolom, tanpa tabel ekstra. Paling populer untuk kasus ini (2.400+ star di GitHub) dan cocok untuk source code produk yang ingin tetap sederhana.

Pilih pendekatan 1 atau 3 kalau kamu membangun source code untuk dijual — pembeli tidak mau instalasi yang rumit.

Apakah website multi-bahasa butuh penyesuaian SEO?

Ya, dan ini bagian yang paling sering dilewatkan. Google memperlakukan /id/tentang dan /en/about sebagai halaman berbeda. Tanpa sinyal yang benar, versi Inggris dan Indonesia bisa dianggap konten duplikat.

Tiga hal minimum yang wajib dipasang:

  1. Tag hreflang di setiap halaman, saling menunjuk antar versi bahasa:
<link rel="alternate" hreflang="id" href="https://domainmu.com/id/tentang" />
<link rel="alternate" hreflang="en" href="https://domainmu.com/en/about" />
<link rel="alternate" hreflang="x-default" href="https://domainmu.com/tentang" />
  1. Locale di URL (/id/..., /en/...) lebih baik untuk SEO daripada locale yang hanya disimpan di session/cookie — Googlebot tidak membawa session.
  2. Canonical self-referencing per versi bahasa, plus terjemahkan juga meta title dan meta description (bisa memakai __() juga).

Kenapa fitur multi-bahasa menaikkan nilai jual source code?

Kalau kamu menjual source code, fitur multi-bahasa adalah pembeda yang konkret:

  1. Pasar lebih luas — source code toko online berbahasa Inggris bisa dijual ke pembeli luar negeri, bukan cuma pasar Indonesia.
  2. Kesan profesional — pembeli menilai kerapian dari detail seperti ini. Source code dengan teks hard-coded campur aduk terlihat seperti project tugas kuliah.
  3. Mudah dikustomisasi pembeli — dengan file lang/, pembeli cukup edit JSON tanpa menyentuh kode. Ini nilai jual yang bisa kamu tulis di deskripsi produk.

Sebutkan di dokumentasi produkmu cara menambah bahasa baru: cukup duplikat id.json jadi ms.json, lalu terjemahkan value-nya.

FAQ

Apakah Laravel punya fitur multi-bahasa bawaan?

Ya. Fitur localization bawaan Laravel menyediakan file terjemahan di direktori lang/, helper __(), pluralisasi trans_choice(), dan pengaturan locale per-request lewat App::setLocale(). Tidak perlu package tambahan untuk teks antarmuka.

Di mana file bahasa Laravel 12 disimpan?

Di direktori lang/ pada root project (sejak Laravel 9, bukan lagi resources/lang). Pada instalasi baru Laravel 11+, folder ini belum ada — buat dengan php artisan lang:publish.

Apa bedanya file JSON dan file PHP untuk terjemahan Laravel?

File JSON (lang/id.json) memakai teks asli sebagai key — praktis untuk teks singkat tersebar di Blade. File PHP (lang/id/messages.php) memakai key terstruktur seperti messages.welcome — lebih rapi untuk teks yang dikelompokkan (misalnya semua label form). Keduanya bisa dipakai bersamaan.

Bagaimana cara menambah bahasa ketiga, misalnya Melayu?

Duplikat lang/id.json menjadi lang/ms.json, terjemahkan value-nya, lalu tambahkan 'ms' ke daftar locale yang diizinkan di route lang/{locale} dan ke tombol switcher. Tidak ada perubahan kode lain.

Apakah teks yang belum diterjemahkan akan error?

Tidak. Jika key tidak ditemukan di file bahasa yang aktif, Laravel menampilkan key itu sendiri. Halaman tetap jalan — hanya teksnya belum berganti bahasa. Ini memudahkan penerjemahan bertahap.

Bisakah locale disimpan di URL seperti /en/about?

Bisa, dengan route group berparameter {locale} plus middleware yang memanggil App::setLocale(). Pola ini lebih SEO-friendly dibanding session karena setiap versi bahasa punya URL unik yang bisa diindeks Google.

Apakah package mcamara/laravel-localization masih diperlukan?

Tidak wajib. Package itu dulu populer untuk locale di URL dan route translatable, tapi kebutuhan dasar (file bahasa, switcher, middleware) sudah terpenuhi fitur bawaan Laravel modern. Pakai package hanya jika butuh fitur lanjut seperti route yang slug-nya ikut diterjemahkan.