JavaScript Integration

Learn how to integrate i18next with vanilla JavaScript applications for internationalization.

Integrate i18next with your vanilla JavaScript application to support multiple languages using Lengrise-managed translations.

Prerequisites

  • JavaScript project
  • Node.js (v16.0.0+)
  • Package manager (npm, yarn, or pnpm)
  • Translations downloaded from Lengrise

Pull Translation Files

First, you must pull your translation files from Lengrise API. These files will contain all the translated text for your application.

  1. Go to the Installation Guide and follow the steps to download your translations
  2. Place the downloaded JSON files in your project as shown in the project structure below
  3. Ensure that each language has its own JSON file named with the language code (e.g., en.json, es.json)

Integration Setup

After downloading your translation files, install the necessary packages:

npm install i18next i18next-http-backend i18next-browser-languagedetector --save

Project Structure

package.jsonadd
index.htmladd
srcadd
index.jsadd
i18n.jsadd
language-switcher.jsadd
localesadd
en.jsonadd
es.jsonadd

Configuration Steps

1. Create i18next configuration

Create a file called src/i18n.js to initialize i18next:

import i18next from "i18next";
import HttpBackend from "i18next-http-backend";
import LanguageDetector from "i18next-browser-languagedetector";

// Initialize i18next
const i18n = i18next
  // Load translations using http backend
  .use(HttpBackend)
  // Detect user language
  .use(LanguageDetector)
  // Initialize i18next
  .init({
    // Default language
    fallbackLng: "en",
    // Supported languages
    supportedLngs: ["en", "es"],
    // Debug mode in development
    debug: process.env.NODE_ENV === "development",

    // Backend configuration to load translations
    backend: {
      // Path to translation files
      loadPath: "/locales/{{lng}}.json",
    },

    // Interpolation settings
    interpolation: {
      escapeValue: false, // Not needed for client-side rendering
    },
  });

// Export initialized i18next instance
export default i18n;

2. Create a language switcher

Create a file called src/language-switcher.js to handle language changes:

import i18n from "./i18n";

// Create language switcher component
export function createLanguageSwitcher(containerId) {
  const container = document.getElementById(containerId);
  if (!container) return;

  // Create language buttons
  const languages = [
    { code: "en", name: "English" },
    { code: "es", name: "EspaƱol" },
  ];

  // Create buttons for each language
  languages.forEach((language) => {
    const button = document.createElement("button");
    button.textContent = language.name;
    button.addEventListener("click", () => {
      i18n.changeLanguage(language.code);
    });
    container.appendChild(button);
  });
}

// Listen for language changes and update the UI
export function onLanguageChanged(callback) {
  i18n.on("languageChanged", callback);
}

3. Implement main application code

Create a file called src/index.js to use the translations:

import i18n from "./i18n";
import { createLanguageSwitcher, onLanguageChanged } from "./language-switcher";

// Wait for the DOM to be ready
document.addEventListener("DOMContentLoaded", () => {
  // Wait for i18next to initialize
  i18n.on("initialized", () => {
    // Create language switcher
    createLanguageSwitcher("language-switcher");

    // Initial translation update
    updateTranslations();

    // Listen for language changes
    onLanguageChanged(updateTranslations);
  });
});

// Update all translations in the UI
function updateTranslations() {
  // Find all elements with data-i18n attribute
  document.querySelectorAll("[data-i18n]").forEach((element) => {
    const key = element.getAttribute("data-i18n");
    element.textContent = i18n.t(key);
  });

  // Find all elements with data-i18n-placeholder attribute
  document.querySelectorAll("[data-i18n-placeholder]").forEach((element) => {
    const key = element.getAttribute("data-i18n-placeholder");
    element.placeholder = i18n.t(key);
  });

  // Find all elements with data-i18n-html attribute
  document.querySelectorAll("[data-i18n-html]").forEach((element) => {
    const key = element.getAttribute("data-i18n-html");
    element.innerHTML = i18n.t(key);
  });
}

// Example of programmatic translation
function translateWithParams(key, params) {
  return i18n.t(key, params);
}

// Expose translation function to global scope (optional)
window.translateWithParams = translateWithParams;

4. Update your HTML file

Update your index.html file to include the scripts and add i18n attributes:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>i18next JavaScript Example</title>
    <!-- Add your CSS files here -->
  </head>
  <body>
    <header>
      <h1 data-i18n="welcome.title">Welcome</h1>
      <div id="language-switcher"></div>
    </header>

    <main>
      <section>
        <h2 data-i18n="welcome.subtitle">Hello World</h2>
        <p data-i18n="welcome.description">This is a multilingual app.</p>
      </section>

      <section>
        <h2 data-i18n="features.title">Features</h2>
        <ul>
          <li data-i18n="features.easy">Easy to use</li>
          <li data-i18n="features.fast">Fast translation</li>
          <li data-i18n="features.flexible">Flexible integration</li>
        </ul>
      </section>

      <!-- Example with parameters -->
      <div id="greeting"></div>
      <script>
        // This will be updated when the page loads
        document.addEventListener("DOMContentLoaded", () => {
          setTimeout(() => {
            const greeting = document.getElementById("greeting");
            greeting.textContent = translateWithParams("greeting", {
              name: "User",
            });
          }, 1000); // Wait for i18next to initialize
        });
      </script>
    </main>

    <!-- Add your script bundle here -->
    <script src="./dist/bundle.js"></script>
  </body>
</html>

Using Translations

HTML Attribute-Based Translation

Use data attributes to mark elements for translation:

<h1 data-i18n="welcome.title">Welcome</h1>
<p data-i18n="about.description">About us text</p>
<input data-i18n-placeholder="form.email" placeholder="Enter your email" />

Programmatic Translation

Access translations in your JavaScript code:

import i18n from "./i18n";

// Simple translation
const title = i18n.t("welcome.title");

// Translation with parameters
const greeting = i18n.t("greeting", { name: "John" });

// Pluralization
const itemCount = i18n.t("items", { count: 5 });

Creating a Custom Component

Example of a reusable translated component:

function createTranslatedButton(containerId, i18nKey, clickHandler) {
  const container = document.getElementById(containerId);
  if (!container) return null;

  const button = document.createElement("button");
  button.textContent = i18n.t(i18nKey);
  button.addEventListener("click", clickHandler);

  // Update button text when language changes
  i18n.on("languageChanged", () => {
    button.textContent = i18n.t(i18nKey);
  });

  container.appendChild(button);
  return button;
}

Handling Variables and Formatting

Use translation keys with variables:

Your JavaScript code:

const formattedText = i18n.t("user.info", {
  name: "Maria",
  count: 5,
  date: new Date(),
});

Your locales/en.json file:

{
  "user": {
    "info": "{{name}} has {{count}} messages since {{date, DD/MM/YYYY}}"
  }
}

Resources

For more detailed information, check out these resources: