You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js Koa2与EJS中实现多语言支持

Scalable Multi-Language Implementation for Koa + EJS

Great question! Your current approach works for two languages, but it'll quickly become unmanageable as you add more locales or expand your text content. Let's refactor this into a clean, scalable setup that's easy to maintain.

Step 1: Create Language Configuration Files

First, move all your translated content out of your code and into dedicated JSON files. This makes adding new languages or updating text a breeze without touching your app logic.

Create a locales folder in your project root, then add files for each language:

locales/en.json:

{
  "title": "Title",
  "welcome": "Welcome to our website!",
  "button": "Click Me"
}

locales/de.json:

{
  "title": "Titel",
  "welcome": "Willkommen auf unserer Website!",
  "button": "Klicken Sie mich"
}

Step 2: Add a Language Loading Utility

Create a simple utility to load the correct language file based on the user's locale. This keeps your route logic clean.

Add a utils/i18n.js file:

const fs = require('fs');
const path = require('path');

function getLanguage(lang) {
  // Default to English if the requested language doesn't exist
  const validLangs = ['en', 'de'];
  const targetLang = validLangs.includes(lang) ? lang : 'en';
  
  const filePath = path.join(__dirname, '../locales', `${targetLang}.json`);
  return JSON.parse(fs.readFileSync(filePath, 'utf8'));
}

module.exports = { getLanguage };

Step 3: Enhance Language Detection Middleware

Right now, your language variable is undefined—let's add logic to detect the user's preferred language from common sources (URL parameter, cookie, or request header):

Update your index.js:

const Koa = require('koa');
const views = require('koa-views');
const path = require('path');
const { getLanguage } = require('./utils/i18n');

const app = new Koa();

// Configure EJS views
app.use(views(path.join(__dirname, './view'), { extension: 'ejs' }));

// Middleware to detect user language
app.use(async (ctx, next) => {
  // Priority order: URL param > Cookie > Accept-Language header > default to en
  let lang = ctx.query.lang || ctx.cookies.get('language');
  
  // Parse Accept-Language header if no other source is found
  if (!lang) {
    const acceptLang = ctx.request.headers['accept-language'];
    if (acceptLang) {
      lang = acceptLang.split(',')[0].split('-')[0]; // Get first language code (e.g., 'de' from 'de-DE')
    }
  }
  
  // Load the language pack and attach to context
  ctx.state.lang = getLanguage(lang);
  
  // Set a cookie to remember the user's language preference
  ctx.cookies.set('language', ctx.state.lang.title === 'Title' ? 'en' : 'de', {
    maxAge: 30 * 24 * 60 * 60 * 1000 // 30 days
  });
  
  await next();
});

// Main route handler
app.use(async (ctx) => {
  // Pass the entire language pack to the template
  await ctx.render('index', { lang: ctx.state.lang });
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

Step 4: Update Your EJS Template

Now you can use all translated content directly in your view/index.ejs template:

<!DOCTYPE html>
<html lang="<%= lang.title === 'Title' ? 'en' : 'de' %>">
<head>
  <meta charset="UTF-8">
  <title><%= lang.title %></title>
</head>
<body>
  <h1><%= lang.welcome %></h1>
  <button><%= lang.button %></button>
  
  <!-- Add language switcher links -->
  <div>
    <a href="?lang=en">English</a> | <a href="?lang=de">Deutsch</a>
  </div>
</body>
</html>

Bonus Optimizations

  • Cache Language Files: For production, cache the loaded JSON files so you don't read from disk on every request.
  • Add More Languages: Just add a new JSON file in the locales folder and update the validLangs array in utils/i18n.js.
  • Handle Complex Translations: If you need plurals, gender-specific text, or variable substitutions later, you could switch to a library like i18next—but this setup works perfectly for most small to medium apps.

内容的提问来源于stack exchange,提问作者yupang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:28:15