REACT I18N INTERNATIONALIZATION LOCALIZATION FRONTEND WEB-DEVELOPMENT DEVELOPER-EXPERIENCE BEST-PRACTICES UI-UX MULTI-LANGUAGE TRANSLATION REACT-HOOKS

Menguasai Internationalization (i18n) di Aplikasi React: Panduan Praktis dengan react-i18next dan Strategi Lanjutannya

⏱️ 8 menit baca
👨‍💻

Menguasai Internationalization (i18n) di Aplikasi React: Panduan Praktis dengan react-i18next dan Strategi Lanjutannya

Halo para developer! Pernahkah Anda membayangkan aplikasi web Anda digunakan oleh orang-orang dari berbagai belahan dunia, masing-masing dengan bahasanya sendiri? Atau mungkin Anda bekerja di sebuah perusahaan yang ingin menjangkau pasar global? Di sinilah Internationalization (i18n), atau sering disebut globalisasi, memainkan peran krusial.

i18n bukan hanya sekadar menerjemahkan teks dari satu bahasa ke bahasa lain. Lebih dari itu, i18n mencakup penyesuaian format angka, tanggal, mata uang, pluralisasi, hingga arah teks (kiri-ke-kanan atau kanan-ke-kiri) agar aplikasi terasa native bagi setiap pengguna. Mengabaikan i18n berarti membatasi potensi aplikasi Anda dan memberikan pengalaman pengguna yang kurang optimal.

Di blog ini, kita sudah pernah membahas panduan umum tentang i18n. Kali ini, kita akan menyelam lebih dalam ke implementasi praktis i18n, khususnya di ekosistem React, menggunakan salah satu library paling populer dan tangguh: react-i18next. Kita akan membahas mulai dari setup dasar hingga strategi lanjutan untuk aplikasi skala besar. Mari kita mulai! 🚀

1. Pendahuluan: Mengapa react-i18next?

Anda mungkin bertanya, mengapa perlu library khusus untuk i18n? Bukankah hanya if (lang === 'en') { ... } sudah cukup? Tentu saja tidak! Pendekatan manual akan menjadi mimpi buruk seiring bertambahnya teks dan bahasa.

react-i18next adalah jembatan antara library i18n inti, i18next, dan React. Library ini menyediakan Hooks dan Components yang memudahkan Anda mengintegrasikan terjemahan ke dalam komponen React Anda dengan cara yang declarative dan efisien.

Keunggulan react-i18next:

Mari kita siapkan proyek React baru dan mulai mengimplementasikannya.

2. Memulai dengan react-i18next: Setup Dasar

Pertama, instal dependency yang diperlukan:

npm install i18next react-i18next i18next-browser-languagedetector --save
# atau
yarn add i18next react-i18next i18next-browser-languagedetector

Selanjutnya, buat file konfigurasi i18n di root proyek Anda, misalnya src/i18n.js:

// src/i18n.js
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';

// Import terjemahan Anda
import translationEN from './locales/en/translation.json';
import translationID from './locales/id/translation.json';

// Objek resource untuk terjemahan
const resources = {
  en: {
    translation: translationEN
  },
  id: {
    translation: translationID
  }
};

i18n
  .use(LanguageDetector) // Mendeteksi bahasa pengguna dari browser
  .use(initReactI18next) // Menghubungkan i18next ke React
  .init({
    resources,
    fallbackLng: 'en', // Bahasa default jika bahasa terdeteksi tidak tersedia
    debug: true, // Aktifkan untuk debugging
    interpolation: {
      escapeValue: false, // React sudah melakukan escaping, jadi tidak perlu lagi
    }
  });

export default i18n;

Buat juga folder src/locales/ dengan subfolder untuk setiap bahasa, misalnya en dan id, dan file translation.json di dalamnya:

// src/locales/en/translation.json
{
  "welcome": "Welcome to our application!",
  "greeting": "Hello, {{name}}!",
  "pluralKey_one": "You have {{count}} new message.",
  "pluralKey_other": "You have {{count}} new messages.",
  "dateExample": "Today is {{date, DATE_HUGE}}.",
  "settings": {
    "title": "Settings",
    "language": "Language"
  }
}
// src/locales/id/translation.json
{
  "welcome": "Selamat datang di aplikasi kami!",
  "greeting": "Halo, {{name}}!",
  "pluralKey_one": "Anda punya {{count}} pesan baru.",
  "pluralKey_other": "Anda punya {{count}} pesan baru.",
  "dateExample": "Hari ini adalah {{date, DATE_HUGE}}.",
  "settings": {
    "title": "Pengaturan",
    "language": "Bahasa"
  }
}

Terakhir, impor file i18n.js ini di file index.js atau main.jsx aplikasi React Anda:

// src/index.js atau src/main.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './i18n'; // Penting: Import konfigurasi i18n Anda
import App from './App';

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

✅ Dengan setup ini, i18next akan otomatis mendeteksi bahasa browser pengguna dan memuat terjemahan yang sesuai.

3. Menggunakan Terjemahan dalam Komponen React

Sekarang, mari kita gunakan terjemahan di komponen App.js kita:

// src/App.js
import React from 'react';
import { useTranslation, Trans } from 'react-i18next';

function App() {
  const { t, i18n } = useTranslation();

  const changeLanguage = (lng) => {
    i18n.changeLanguage(lng);
  };

  const today = new Date();

  return (
    <div style={{ padding: '20px', maxWidth: '600px', margin: '0 auto' }}>
      <h1>{t('welcome')}</h1>
      <p>{t('greeting', { name: 'Dunia' })}</p>

      <h2>{t('settings.title')}</h2>
      <p>{t('settings.language')}:</p>
      <button onClick={() => changeLanguage('en')} style={{ marginRight: '10px' }}>English</button>
      <button onClick={() => changeLanguage('id')}>Bahasa Indonesia</button>

      <h3>Pluralisasi</h3>
      <p>{t('pluralKey', { count: 1 })}</p> {/* Output: Anda punya 1 pesan baru. */}
      <p>{t('pluralKey', { count: 5 })}</p> {/* Output: Anda punya 5 pesan baru. */}
      <p>{t('pluralKey', { count: 0 })}</p> {/* Output: Anda punya 0 pesan baru. */}

      <h3>Format Tanggal</h3>
      <p>{t('dateExample', { date: today })}</p>

      <h3>Interpolasi dengan Komponen React (`Trans`)</h3>
      <p>
        <Trans i18nKey="complexText">
          Silakan kunjungi <a href="https://blog.example.com">blog kami</a> untuk informasi lebih lanjut.
        </Trans>
      </p>
      {/* Untuk ini, Anda perlu menambahkan "complexText" di translation.json */}
      {/* "complexText": "Silakan kunjungi <1>blog kami</1> untuk informasi lebih lanjut." */}
    </div>
  );
}

export default App;

Tambahkan complexText ke file translation.json Anda:

// src/locales/en/translation.json
{
  // ...
  "complexText": "Please visit <1>our blog</1> for more information."
}
// src/locales/id/translation.json
{
  // ...
  "complexText": "Silakan kunjungi <1>blog kami</1> untuk informasi lebih lanjut."
}

📌 Penting:

4. Manajemen Terjemahan yang Efisien: Namespaces dan Lazy Loading

Untuk aplikasi skala besar, menempatkan semua terjemahan dalam satu file translation.json akan membuatnya sulit dikelola dan memperlambat loading. i18next mendukung namespaces dan lazy loading untuk mengatasi ini.

Namespaces

Anda bisa membagi terjemahan berdasarkan fitur atau bagian aplikasi (misalnya common, dashboard, auth).

  1. Buat folder locales/en/ dan locales/id/ menjadi seperti ini:

    src/locales/
    ├── en/
    │   ├── common.json
    │   └── dashboard.json
    └── id/
        ├── common.json
        └── dashboard.json
  2. Isi common.json:

    // src/locales/en/common.json
    {
      "welcome": "Welcome to our app!",
      "greeting": "Hello, {{name}}!"
    }
    // src/locales/id/common.json
    {
      "welcome": "Selamat datang di aplikasi kami!",
      "greeting": "Halo, {{name}}!"
    }

    Isi dashboard.json:

    // src/locales/en/dashboard.json
    {
      "title": "Dashboard Overview",
      "userCount": "Total users: {{count}}"
    }
    // src/locales/id/dashboard.json
    {
      "title": "Ikhtisar Dashboard",
      "userCount": "Total pengguna: {{count}}"
    }
  3. Update konfigurasi i18n.js Anda:

    // src/i18n.js
    // ...
    i18n
      // ...
      .init({
        // ...
        ns: ['common', 'dashboard'], // Daftarkan semua namespaces yang akan digunakan
        defaultNS: 'common', // Namespace default jika tidak disebutkan
        // ...
      });
    // ...
  4. Saat menggunakan useTranslation, Anda bisa menentukan namespace:

    import React from 'react';
    import { useTranslation } from 'react-i18next';
    
    function DashboardHeader() {
      // Menggunakan namespace 'dashboard'
      const { t } = useTranslation('dashboard');
      return (
        <h2>{t('title')}</h2>
      );
    }
    
    function WelcomeMessage() {
      // Menggunakan namespace default (common)
      const { t } = useTranslation();
      return (
        <p>{t('welcome')}</p>
      );
    }

Lazy Loading Terjemahan

Untuk memuat terjemahan hanya saat dibutuhkan (misalnya, saat pengguna mengganti bahasa atau menavigasi ke halaman tertentu), Anda bisa menggunakan i18next-http-backend dan React Suspense.

  1. Instal i18next-http-backend:

    npm install i18next-http-backend --save
  2. Update i18n.js:

    // src/i18n.js
    import i18n from 'i18next';
    import { initReactI18next } from 'react-i18next';
    import LanguageDetector from 'i18next-browser-languagedetector';
    import HttpBackend from 'i