i18next HTTP Backend
i18next-http-backend is a backend layer for the i18next internationalization framework, designed to load translation resources from a remote server using standard HTTP requests (XMLHttpRequest or Fetch API). It supports diverse JavaScript environments, functioning seamlessly in Node.js, modern browsers, and Deno. Currently at stable version 3.0.5, it receives updates as needed to maintain compatibility and introduce improvements. It's explicitly designed as a modern, drop-in replacement for the deprecated i18next-xhr-backend, addressing its limitations. Its primary differentiation is its broad platform support and direct integration with i18next's resource loading mechanism, enabling developers to manage translations externally without bundling them into the client-side application. It offers configurable options for request handling, retry logic, and resource path resolution.
Common errors
-
Seeing failed http requests, like 404?
cause A language detector requests a region-specific language (e.g., 'en-US') for which no translation is provided, the 'loadPath' is incorrect, or the backend server is not serving the files.fixSet `i18next.init({ load: 'languageOnly' })` to prevent requests for region-specific languages. Verify `backend.loadPath` is correct and that your server is configured to serve the translation files at that path with appropriate CORS headers. -
Slow i18next initialization?
cause HTTP requests for translation files are failing, causing i18next to retry multiple times before giving up, leading to delays.fixAnalyze HTTP requests and fix the root cause (e.g., incorrect `loadPath`, server misconfiguration). Alternatively, configure `i18next.init({ retryTimeout: 350, maxRetries: 1 })` to reduce retry attempts and hasten initialization when requests are failing.
Warnings
- breaking i18next-http-backend is a direct replacement for the deprecated i18next-xhr-backend. While largely a drop-in replacement, be aware of subtle differences in how HTTP requests are handled (Fetch API vs. XMLHttpRequest) which might affect custom configurations or older browser compatibility if not properly polyfilled.
- gotcha Encountering 404 errors for region-specific languages (e.g., requesting 'en-US' when only 'en' translations are provided) is a common issue. This often happens if an i18next language detector is active and the `load` option is set to its default 'all'.
- gotcha Slow i18next initialization can occur if HTTP requests for translation files fail. i18next is configured to retry these requests multiple times by default, leading to delays before it completes initialization.
- gotcha Version 3.0.0 introduced breaking changes for ESM build environments that do not support top-level await, and addressed security vulnerabilities.
Install
-
npm install i18next-http-backend -
yarn add i18next-http-backend -
pnpm add i18next-http-backend
Imports
- HttpBackend
import { HttpBackend } from 'i18next-http-backend';import HttpBackend from 'i18next-http-backend';
- HttpBackend (CommonJS)
const HttpBackend = require('i18next-http-backend').default;const HttpBackend = require('i18next-http-backend'); - HttpBackendOptions (Type)
import type { HttpBackendOptions } from 'i18next-http-backend';
Quickstart
import i18next from 'i18next';
import HttpBackend from 'i18next-http-backend';
// In a real application, translation files would be served from a web server.
// This example uses a mock fetch to simulate loading.
const mockTranslations = {
en: {
translation: {
"welcome": "Welcome to our app!",
"greeting": "Hello, {{name}}!"
}
},
es: {
translation: {
"welcome": "¡Bienvenido a nuestra aplicación!",
"greeting": "¡Hola, {{name}}!"
}
}
};
// Simulate a fetch function that would load resources from a URL
const mockFetch = async (url: string) => {
console.log(`Simulating fetch for: ${url}`);
const parts = url.split('/');
const lang = parts[parts.length - 2]; // e.g., 'en' from '/locales/en/translation.json'
const ns = parts[parts.length - 1].split('.')[0]; // e.g., 'translation'
if (mockTranslations[lang as keyof typeof mockTranslations] && mockTranslations[lang as keyof typeof mockTranslations][ns as keyof typeof mockTranslations[keyof typeof mockTranslations]]) {
return {
ok: true,
status: 200,
json: () => Promise.resolve(mockTranslations[lang as keyof typeof mockTranslations][ns as keyof typeof mockTranslations[keyof typeof mockTranslations]])
};
}
return {
ok: false,
status: 404,
json: () => Promise.resolve({}) // Return empty object for 404
};
};
i18next
.use(HttpBackend)
.init({
lng: 'en',
fallbackLng: 'en',
debug: true, // Enable debug for more console output
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json',
// Provide a custom request function to use the mock fetch
request: (options, url, payload, callback) => {
mockFetch(url)
.then(response => {
if (response.ok) {
response.json().then(data => callback(null, { status: response.status, data }));
} else {
callback(new Error(`Failed to load ${url}: ${response.status}`), { status: response.status });
}
})
.catch(error => callback(error, { status: 0 }));
}
},
ns: ['translation'], // Default namespace
defaultNS: 'translation',
interpolation: {
escapeValue: false, // React already escapes by default
},
})
.then(() => {
console.log(i18next.t('welcome'));
console.log(i18next.t('greeting', { name: 'World' }));
console.log(i18next.t('missingKey')); // This will show as 'missingKey' due to no translation
// Change language and translate again
i18next.changeLanguage('es').then(() => {
console.log(i18next.t('welcome'));
});
})
.catch((err) => console.error("i18next initialization error:", err));