Implementasi Fitur Translation i18n pada project Next Js.

Diko_Mahendra
6 min readFeb 11, 2023

--

Halo semuanya, jadi beberapa waktu lalu aku dapet tugas untuk membuat sebuah fitur ubah bahasa. untuk hampir semua halaman yg ada pada project tersebut. dengan memanfaatkan library i18n pada Next Js.

sedikit cerita tentang penggunaan i18n , sebenarnya library ini tidak hanya sebuah fitur untuk merubah bahasa seperti indonesia — inggris atau inggris — indonesia, dsb. tapi ada sebuah management content (bersifat static) yg sangat baik, yg bisa kita terapkan dengan memanfaatkan library ini. yg dimana setiap content dari semua halaman yg ada, akan terkumpul di 1 folder, yang biasa diberi nama dengan locales. dengan demikian proses perubahan copy writing / wording pada setiap page / component akan sangat mudah, tanpa harus melakukan deep tracing component.

tanpa berlama-lama langsung saja kita mulai.

Let’s goooooo…..

pertama tama kita akan siapkan dulu project next js kita, kalian bisa langsung cek saja di dokumentasi resmi pada nextjs.

disini kita akan menggunakan next 13.

tapi perlu dicatat untuk opsi “Would you like to use experimental ‘app/’ directory”. wajib kalian pilih No, karena akan ada perbedaan struktur folder dan cara implementasi ketika menggunakan /app. dan fitur ini sedang dalam tahap experiment / beta version.

jika sudah selesai, langsung saja kita ke tahap installasi package yg kita butuhkan.

npm install next-i18next

jika sudah, waktunya kita rapihkan directory dan file-file yg tidak kita butuhkan. disini kita akan membuat sebuah tampilan sederhana yg hanya menampilkan sebuah text dan button untuk ubah bahasa inggris — indonesia atau indonesia — inggris.

dengan ini aku harap kalian bisa explore lebih dalam dan mencoba meng implementasikannya di real project yg kalian miliki.

Lanjutt….

ini adalah struktur folder yg belum kita rubah, dan masih murni dari apa yg kita install sebelumnya, kita akan coba hapus beberapa file, di antaranya Home.module.css kemudian /api dan beberapa icon yg ada pada folder /public. kenapa dihapusin? suka aja awkwk karena terlalu rame sih, dan yg dibutuhkan cuma sedikit. kurang lebih akan seperti ini penampakannya.

kemudian kita pergi ke direktory _app.js dan kita bungkus component App ke dalam appWithTranslation .

import '@/styles/globals.css'
import { appWithTranslation } from 'next-i18next';

function App({ Component, pageProps }) {
return <Component {...pageProps} />
}

export default appWithTranslation(App)

kemudian buat file baru dengan nama next-i18next.config.js. kita akan menambahkan beberapa attribute untuk mengatur default bahasa yg kita gunakan, dsb.

module.exports ={
i18n: {
defaultLocale: 'id',
locales: ['en', 'id'],
localePath: './locales',
localeDetection: false,
}
}

pergi ke file next.config.js dan tambahkan i18n pada nextConfig, import dari file next-i18next.config.js yg sebelumnya kita buat.

/** @type {import('next').NextConfig} */
const { i18n } = require('./next-i18next.config')

const nextConfig = {
i18n,
reactStrictMode: true,
}

module.exports = nextConfig

kalau sudah, waktunya kita buat folder /locales dan kita tempatkan pada direktory paling luar / root directory di project kita , disini kita akan membuat 2 folder yaitu en, id. yg di dalamnya terdapat sebuah file dengan format json (common.json).

akan terlihat seperti ini.

selanjutkan akan kita tambahkan content untuk masing-masing bahasa pada file common.json di kedua folder id & en.

okay semua persiapan sudah dilakukan, tinggal implementasi pada halaman yg kita inginkan, disini kita akan pergi ke folder pages/index.js

tambahkan baris code seperti dibawah ini:

import { useState } from 'react';
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

export default function Home() {
const router = useRouter()
const { t } = useTranslation('common');
const { title, description } = t('home', { returnObjects: true })
const [language, setLanguage] = useState("en")

const handleChangeLangue = () => {
language=="en" ? setLanguage("id") : setLanguage("en")
const asPath = router.asPath
return router.push(asPath, asPath, { locale: language });
}

return (
<div>
<h1>{title}</h1>
<p>{description}</p>

<button onClick={handleChangeLangue}>
{router.locale === 'en' ? 'Indonesia' : 'English'}
</button>
</div>
)
}


export async function getStaticProps(context) {
const { locale } = context
return {
props: {
...(await serverSideTranslations(locale, ['common']))
}
}
}

mari sedikit kita breakdown kode di atas.

getStaticProps : metode ini digunakan untuk mengambil data yg diperlukan sebelum halaman tersebut di render atau ditampilkan dibrowser. cocok digunakan kalau data kita bersifat static, tidak atau jarang berubah-ubah.

serverSideTranslations: sebuah fungsi yg disedian oleh next-i18next untuk mengambil terjemahan di sisi server dan digunakan untuk mengambil terjemahan pada proses build-time. menerima 2 parameter.

Parameter Pertama: untuk mempresentasikan bahasa yg ingin digunakan seperti [“en”, “id, “fr”] dsb.

Parameter Kedua: untuk mempresentasikan terjemahan yg ingin kita ambil, kalau kalian cek folder /locales yg ada pada root directory yg kita buat. disitu ada sebuah file dengan format json. yg kita beri nama common.json, nah dari nama file itulah parameter ke 2 ini berasal. jadi kalau seandainya kita tambahkan 1 file lagi dengan nama product.json, maka kalau ingin mengambil content terjemahan yg ada pada file product.json, cukup menambahkan string “product” pada array tsb.

untuk menggunakan translation yg kita buat, cukup mudah.

const { t } = useTranslation('common');
const { title, description } = t('home', { returnObjects: true })

kita akan ambil content translation yg ada pada file common.json, kemudian disini kita masuk kedalam object “home” yg memiliki data title, dan juga description, dan kemudian kita destructuring variable { t } . menjadi seperti ini

const { title, description } = t('home', {  returnObjects: true })

setelah itu kita akan membuat sebuah state yg menyimpan sebuah default value berupa string berfungsi sebagai penanda bahasa yg digunakan.

const [language, setLanguage] = useState("en")

kemudian kita akan buat sebuah function yg berfungsi untuk mengubah state language , dan akan melakukan router.push dengan 3 paremeters, parameters 1 & 2 hampir mirip bisa digunakan sebagai href, kemudian paremeter — 3 kita gunakan untuk mengatur locale / bahasa yg ingin kita gunakan. disini saya akan mengatur value locale dengan data language yg ada (“en” / “id”). english / indonesia.

const handleChangeLangue = () => {
language=="en" ? setLanguage("id") : setLanguage("en")
const asPath = router.asPath
return router.push(asPath, asPath, { locale: language });
}

oke sepertinya sudah cukup untuk halaman ini, namun masih ada yg kurang, karena kita perlu menambahkan sebuah function yg akan mengatur perubahan bahasa secara global pada aplikasi kita.

mari kita pergi file _app.js disini kita akan menambahkan beberapa baris code.

// file _app.js

import '@/styles/globals.css'
import { appWithTranslation, useTranslation } from 'next-i18next';
import { useRouter } from 'next/router';
import { useEffect } from 'react';

function App({ Component, pageProps }) {
const { locale } = useRouter();
const { i18n } = useTranslation();

useEffect(() => {
i18n.changeLanguage(locale)
}, [locale, i18n])

return <Component {...pageProps} />
}

export default appWithTranslation(App)

pertama: kita perlu mengambil data locale yg akan kita gunakan sebagai parameter untuk mengatur nilai / bahasa yg digunakan.

kedua: buat sebuah useEffect yg memiliki dependencies berupa locale, dan i18n, ini akan melakukan perubah setiap kali ada perubahan pada router.locale kemudian i18n akan melakukan perubahan bahasa yg dinamis sesuai dengan locale / bahasa yg sedang digunakan atau aktif saat ini.

kalau berhasil maka akan berjalan seperti ini.

selamat bereksplorasi, semoga tulisan ini membantu. jangan sungkan kalau ada kritik dan saran. terimakasih telah berkunjung :)

--

--