Internationalize di NUXT dengan Vue-i18n
Kebetulan ada permintaan membuat fitur ubah bahasa di aplikasi yang sedang dibuat, karena sedang mengerjakan di NUXT saya nemu nuxt-i18n di bagian community, namun gagal saya terapkan mungkin saya yang kurang sabar dalam ngedebug. Akirnya saya ikuti pepatah kuno “banyak jalan menuju Roma” karena yang itu gak berhasil, saya cari cara lain, akhirnya saya menemukan cara yang bagi saya jauh lebih mudah yaitu dengan vue-i18n. Bagaimana caranya? Langsung saja.
Dalam tulisan ini tidak akan membahas bagaimana mengubah seluruh konten, di sini yang diubah hanya sekadar label-label dari menu ataupun judul sebuah halaman.
Di sini perubahan bahasa memanfaatkan query string
bukan segment
sehinga hasil akhirnya seperti berikut
http://blog.arsmp.com/?lang=id
bukan
http://blog.arsmp.com/id/
Saya berasumsi semua udah pasang NUXT dan lainnya, maka untuk memasang plugin vue-i18n kita cukup ketikan perintah berikut
npm i vue-i18n
Tunggu sampai selesai.
Persiapan
Saya di sini membuat 2 halaman saja index
dan about
dan satu komponen navbar
.
index.vue
<template> <div> <div class="starter-template"> <h1>Ini Beranda !!11!!!11</h1> <p class="lead">Ini Konten mah tetep, yang diubah cuma menu dan judul halaman saja ~</p> </div> </div> </template>
about.vue
<template> <div> <div class="starter-template"> <h1>Ini Halaman Tentang Kami !!11!!!</h1> <p class="lead">Ini Konten mah tetep, yang diubah cuma menu dan judul halaman saja ~</p> </div> </div> </template>
components/navbar.vue
<template> <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <!-- The mobile navbar-toggle button can be safely removed since you do not need it in a non-responsive implementation --> <a class="navbar-brand" href="#">Alih Bahasa</a> </div> <!-- Note that the .navbar-collapse and .collapse classes have been removed from the #navbar --> <div id="navbar"> <ul class="nav navbar-nav"> <li> <nuxt-link to="/">Home</nuxt-link> </li> <li> <nuxt-link to="/about">About</nuxt-link> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Ganti Bahasa <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Indonesia</a></li> <li><a href="#">English</a></li> </ul> </li> </ul> </div><!--/.nav-collapse --> </div> </nav> </template>
Sehingga tampilannya akan sebagai berikut
Untuk bahasa kita akan siapkan lokasi atau berkas terjemahan di root
folder, tambahkan folder baru, saya beri nama locales
dan di dalamnya saya tambahkan berkas json bahasa.
locales
├── en.json
└── id.json
Isi masing-masing berkas seperti berikut
id.json
{ "links": { "home": "Beranda", "about": "Tentang" }, "pages": { "home": "Ini Beranda !!11!!!11", "about": "Ini Halaman Tentang Kami !!11!!!" } }
en.json
{ "links": { "home": "Home", "about": "About" }, "pages": { "home": "This Is HOMEPAGE !!11!!!11", "about": "This Is ABOUT !!11!!!" } }
Selanjutnya kita akan buat plugin
buat berkas baru lokasi berikut plugins/i18n.js
import Vue from "vue" import VueI18n from "vue-i18n" Vue.use(VueI18n) export default ({ app, store }) => { // di sini kita akan memanfaat kan store (vuex) app.i18n = new VueI18n({ // `locale` akan mengambil dari locale default di store(vuex) locale: store.state.locale, fallbackLocale: "id", //selalu gunakan ID jika kaga ada Inggris messages: { //lokasi file terjemahan en: require("~/locales/en.json"), id: require("~/locales/id.json") } }) }
Setelah plugin yang kita butuhkan adalah middleware dimana dia akan mengatur bahasa semua halaman.
middleware/i18n.js
export default function({ isHMR, app, store, route, params, error, redirect }) { // ambil const defaultLocale = app.i18n.fallbackLocale // jika halaman bersumber dari url langsung atau hot reload abaikan saja if (isHMR) return // jika tidak ada query string 'lang' ambil defaultlocale yaitu id let locale = route.query.lang || defaultLocale // jika tidak ditemukan di state vuex paksa jadi id if (store.state.locales.indexOf(locale) === -1) { locale = defaultLocale } //ubah state locale jadi locale yang dipilih store.commit("SET_LANG", locale) // Set locale dari query string '?lang='**'' app.i18n.locale = store.state.locale }
Dari plugin maupun middleware semuanya menggunakan store
maka dari itu kita buat store(vuex) terlebih dahulu. Buat berkas index.js
di folder store
store/index.js
export const state = () => ({ locales: ["id", "en"], locale: "id" }); export const mutations = { SET_LANG(state, locale) { if (state.locales.indexOf(locale) !== -1) { state.locale = locale; } } };
Oke persiapan awal sudah, selanjutnya bahan-bahan di atas kita tambahkan di nuxt.config.js
module.exports = { // ... konfigurasi lainnya plugins: ["plugins/i18n.js"], router: { middleware: ["i18n"] } // konfigurasi lainnya }
Selanjutnya jalankan aplikasi
npm run dev
Mengubah Bahasa
Untuk mengubah bahasa kita cukup tambah satu methods
di navbar
, dan juga tambahkan query string
di target url.
<template> <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <!-- The mobile navbar-toggle button can be safely removed since you do not need it in a non-responsive implementation --> <a class="navbar-brand" href="#">Alih Bahasa</a> </div> <!-- Note that the .navbar-collapse and .collapse classes have been removed from the #navbar --> <div id="navbar"> <ul class="nav navbar-nav"> <li> <nuxt-link :to="'/?lang='+this.$store.state.locale">Home</nuxt-link> </li> <li> <nuxt-link :to="'/about?lang='+this.$store.state.locale">About</nuxt-link> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Ganti Bahasa <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="javascript:void(1);" @click="setLang('id')">Indonesia</a></li> <li><a href="javascript:void(1);" @click="setLang('en')">English</a></li> </ul> </li> </ul> </div><!--/.nav-collapse --> </div> </nav> </template> <script> export default { methods: { setLang(lang) { // ubah nilai state bahasa this.$store.commit('SET_LANG',lang) //set ulang router dgn menambahkan query string lang berdasarkan lang yang dipilih this.$router.push({ path: `${this.$router.currentRoute.path}?lang=${lang}` }) } } } </script>
Sekarang coba ubah pilih dropdown pilih bahasa dan perhatikan url. Bertambah query string
namun label-label tidak berubah.
Agar berubah itu mudah, cukup ubah label yang diubah seperti berikut
Pada navbar
<li> <nuxt-link :to="'/?lang='+this.$store.state.locale">{{$t('links.home')}}</nuxt-link> </li> <li> <nuxt-link :to="'/about?lang='+this.$store.state.locale">{{$t('links.about')}}</nuxt-link> </li>
Pada masing-masing konten halaman
index.vue
<template> <div> <div class="starter-template"> <h1>{{$t('pages.home')}}</h1> <p class="lead">Ini Konten mah tetep, yang diubah cuma menu dan judul halaman saja ~</p> </div> </div> </template>
about.vue
<template> <div> <div class="starter-template"> <h1>{{$t('pages.about')}}</h1> <p class="lead">Ini Konten mah tetep, yang diubah cuma menu dan judul halaman saja ~</p> </div> </div> </template>
Lalu perhatikan kembali.
Semoga bermanfaat ~
Referensi:
https://medium.com/@helena.wu87/how-to-internationalize-your-next-nuxt-project-using-vue-i18n-d9c51e28a564
Repositori:
https://gitlab.com/ariesmaulana/nuxt-internationalize
0 Comments