ExpressJS - Internationalization(i18n)
Express.js - Modern Internationalization (i18n)
Section titled “Express.js - Modern Internationalization (i18n)”Internationalization, often abbreviated as i18n, is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes. This tutorial demonstrates how to implement i18n in a modern Express.js application.
Core Libraries
Section titled “Core Libraries”We will use a robust and popular set of libraries to handle translations:
- i18next: The core i18n framework, providing the main translation functionality.
- i18next-http-middleware: A modern middleware to detect the user’s language and integrate i18n capabilities into Express requests and responses.
- i18next-fs-backend: A backend module for i18next that loads translation resources from the local file system.
Project Setup
Section titled “Project Setup”First, initialize a new Node.js project and install Express and the required i18n modules.
# 1. Create a new project directorymkdir express-i18n-example && cd express-i18n-example
# 2. Initialize a Node.js projectnpm init -y
# 3. Install dependenciesnpm install express i18next i18next-http-middleware i18next-fs-backendCreating Translation Files
Section titled “Creating Translation Files”Organize your translation files in a structured way. A common practice is to have a locales directory with subdirectories for each language.
Project Folder Structure
Section titled “Project Folder Structure”.├── locales/│ ├── en/│ │ └── translation.json│ └── fr/│ └── translation.json├── node_modules/├── index.js└── package.jsonlocales/en/translation.json
Section titled “locales/en/translation.json”{ "welcome": "Welcome to our modern Express application!", "greeting": "Hello, {{name}}! We are glad to have you here."}locales/fr/translation.json
Section titled “locales/fr/translation.json”{ "welcome": "Bienvenue dans notre application Express moderne !", "greeting": "Bonjour, {{name}} ! Nous sommes ravis de vous avoir ici."}Initializing and Using i18next
Section titled “Initializing and Using i18next”Now, let’s configure i18next and apply its middleware in our main application file, index.js.
// index.jsimport express from 'express';import i18next from 'i18next';import Backend from 'i18next-fs-backend';import middleware from 'i18next-http-middleware';
// Initialize i18nexti18next .use(Backend) // Loads translations from the file system .use(middleware.LanguageDetector) // Detects user language from request .init({ fallbackLng: 'en', backend: { loadPath: './locales/{{lng}}/translation.json', }, detection: { order: ['querystring', 'cookie', 'header'], caches: ['cookie'], lookupQuerystring: 'lang', // e.g., /?lang=fr lookupCookie: 'i18next', }, // It's recommended to escape values to prevent XSS attacks // if not using a frontend library that already does it. interpolation: { escapeValue: true } });
const app = express();const PORT = process.env.PORT || 3000;
// Apply the i18next middlewareapp.use(middleware.handle(i18next));
// --- Routes ---app.get('/', (req, res) => { // The t function is added to the req object by the middleware res.status(200).send(req.t('welcome'));});
app.get('/greet/:name', (req, res) => { const { name } = req.params; res.status(200).send(req.t('greeting', { name }));});
// Basic error handlingapp.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something broke!');});
app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`);});Key Configuration Explained
Section titled “Key Configuration Explained”importsyntax: We use modern ES6 module syntax. To enable this, add"type": "module"to yourpackage.jsonfile..use(Backend): Configuresi18next-fs-backendto read translation JSON files..use(middleware.LanguageDetector): This powerful detector automatically finds the user’s preferred language by checking (in order) a query string parameter (?lang=fr), a cookie, and theAccept-LanguageHTTP header.fallbackLng: 'en': If a translation key is not found in the detected language, it will fall back to English.app.use(middleware.handle(i18next)): This is the crucial step that integratesi18nextinto the Express request-response cycle, making thereq.t()function available in all subsequent routes.
Testing the Application
Section titled “Testing the Application”Run your server with node index.js. You can now test the different language outputs.
- Default (English): Open your browser or use curl:
curl http://localhost:3000/ - French via Query String:
curl "http://localhost:3000/?lang=fr" - Greeting in English:
curl http://localhost:3000/greet/Alex - Greeting in French:
curl "http://localhost:3000/greet/Alex?lang=fr"
Common Errors and Debugging
Section titled “Common Errors and Debugging”- Translations Not Loading: Double-check the
loadPathin youri18next.init()configuration. Ensure it correctly points to yourlocalesdirectory relative to where you run the node process. req.t is not a function: This error means thei18next-http-middlewareis not correctly configured or is placed after your routes. Ensureapp.use(middleware.handle(i18next));comes before you define any routes.- ESM
importSyntax Error: If you see an error likeSyntaxError: Cannot use import statement outside a module, make sure you have added"type": "module"to yourpackage.jsonfile.