Episode ini membahas internationalization di App Router memakai next-intl, routing lokalized dengan prefix bahasa dan deteksi locale lewat middleware, terjemahan konten, serta SEO dan metadata untuk aplikasi multi-bahasa.

Aplikasi yang menjangkau banyak negara butuh lebih dari sekadar terjemahan: kalian harus menangani routing berdasarkan bahasa, format tanggal dan angka, arah teks, serta URL yang ramah SEO untuk tiap bahasa. Inilah dunia internationalization.
Episode 11 membahas dukungan i18n di App Router memakai next-intl, routing lokalized dan deteksi bahasa lewat middleware, pengelolaan terjemahan konten, serta SEO dan metadata untuk aplikasi multi-bahasa.
App Router tidak menyediakan solusi i18n bawaan satu-untuk-semua; pendekatan yang direkomendasikan adalah routing berbasis segment: buat segment dinamis [locale] di akar aplikasi, lalu library seperti next-intl atau next-i18next mengelola pesan dan format. next-intl adalah pilihan paling populer untuk App Router karena mendukung komponen server.
Pertama, install dependency dan buat struktur folder:
npm install next-intlStruktur aplikasi menjadi app/[locale]/layout.tsx dan app/[locale]/page.tsx. Setiap bahasa punya file pesan di folder messages, misalnya messages/id.json dan messages/en.json.
Gunakan getRequestConfig untuk memuat pesan berdasarkan locale:
import { getRequestConfig } from "next-intl/server"
export default getRequestConfig(async ({ requestLocale }) => {
const locale = await requestLocale
return {
locale,
messages: (await import(`../messages/${locale}.json`)).default,
}
})Konfigurasi di atas memuat file pesan sesuai locale aktif. Fungsi ini dieksekusi per request, sehingga pesan selalu konsisten dengan bahasa yang sedang dilihat pengguna.
Di komponen, panggil fungsi useTranslations untuk mengakses pesan:
import { useTranslations } from "next-intl"
export default function HomePage() {
const t = useTranslations("Home")
return <h1>{t("title")}</h1>
}t("title") membaca kunci Home.title dari file pesan bahasa aktif. Saat pengguna berpindah bahasa, teks berubah tanpa reload halaman penuh.
Middleware di middleware.ts memilih locale berdasarkan preferensi browser atau URL, lalu melakukan redirect ke segment bahasa:
import createMiddleware from "next-intl/middleware"
export default createMiddleware({
locales: ["id", "en"],
defaultLocale: "id",
})
export const config = {
matcher: ["/", "/(id|en)/:path*"],
}Middleware createMiddleware di atas mengarahkan pengguna yang datang ke / ke /id atau /en berdasarkan preferensi bahasa mereka. Konfigurasi locales dan defaultLocale menetapkan bahasa yang tersedia.
File pesan diorganisir per namespace:
{
"Home": {
"title": "Selamat datang",
"description": "Aplikasi multi-bahasa"
}
}Namespace Home di atas memisahkan pesan per halaman atau fitur. Konsistensi kunci antar file bahasa mencegah terjemahan yang hilang — library akan melempar peringatan saat kunci tidak ditemukan.
Untuk SEO multi-bahasa, setiap halaman perlu tag hreflang yang memberi tahu Google hubungan antar versi bahasa. next-intl menyediakan fungsi getAlternateLinks dan getLocalizedPathnames untuk menghasilkan tautan alternatif secara otomatis. Lengkapi dengan metadata lokal:
export async function generateMetadata({ params }) {
const { locale } = await params
return {
title: locale === "id" ? "Beranda" : "Home",
alternates: {
languages: { "id-ID": "/id", "en-US": "/en" },
},
}
}Objek alternates.languages menghasilkan tag hreflang yang menautkan semua versi bahasa. Setiap bahasa juga punya URL sendiri — ini membuat Google mengindeks tiap versi dengan benar, tanpa konten duplikat.
Inti yang harus dibawa pulang:
Di episode 12 selanjutnya kita akan membahas authentication dan authorization — pola autentikasi di Next.js, integrasi NextAuth.js atau Auth.js, melindungi route dengan middleware dan session management, serta role-based access control dan secure redirect. Keamanan akses aplikasi kalian mulai dibangun.