mdv
mdv

Reputation: 945

Express and i18n default locale not working

Im trying to set up i18n-node and Expressjs. My conf is this:

// i18n Configuration =========================================================

var i18nconf = {
   locales        : ["en", "es"],
   cookie         : "locale",
   defaultLocale : "en",
   directory      : path.join(__dirname, "lang"),
   indent : "  "
};

i18n.configure(i18nconf);
app.use(i18n.init);

There are 2 locales on lang/ folder en.json and es.json, I can switch between them no problem but express always load es.json as default, somehow is ignoring defaultLocale: 'en' in the conf.

any ideas?

Thanks in advance!

Upvotes: 3

Views: 6335

Answers (6)

Baris Senyerli
Baris Senyerli

Reputation: 920


const i18n = new I18n({
  locales: ["en", "sv", "tr"],
  directory: path.join(__dirname, "locales"),
  defaultLocale: "en",
  cookie: "locale",
  directory: __dirname + "/locales",
  directoryPermissions: "755",
  autoReload: true,
  updateFiles: true,
  objectNotation: true,
  api: {
    __: "__",
    __n: "__n",
  },
});

app.use(i18n.init);

// Set up middleware to change the language based on query parameter or cookie
app.use((req, res, next) => {
  let locale =
    req?.query?.lang || req?.cookies?.locale || i18n.getLocale() || "en";
  i18n.removeLocale(req); // Remove the locale from the request object
  i18n.setLocale(locale); // Set the locale for the response
  req.i18n = i18n; // Add i18n to the request object
  next();
});

Simply my solution is worked only remove and set.

Upvotes: 0

Thomas Pelster
Thomas Pelster

Reputation: 1

I's a very old question, but the replacement with defaults only happens when the 'retryInDefaultLocale' property is set.

var i18nconf = {
   locales        : ["en", "es"],
   cookie         : "locale",
   defaultLocale : "en",
   retryInDefaultLocale: true,
   directory      : path.join(__dirname, "lang"),
   indent : "  "
};

Upvotes: 0

Sebastian Pikand
Sebastian Pikand

Reputation: 11

Here is a solution that works for me. I wanted to site to be in Chinese by default. I also have 2 language change buttons in the navbar (flag images) that go to /en & /zh routes, which set the cookie and redirect the user back to the page they came from.

Tested it with incognito window and by clearing the cookie and refreshing the site. First load in ZH and language change works by adding/changing the cookie value.

I also had to init i18n BEFORE using req.setLocale() in my middleware.

const express = require('express');
const hbs = require('express-hbs');
const i18n = require('i18n');
const app = express();
const cookieParser = require('cookie-parser');

const indexRoutes = require('./routes/indexRoutes');

app.engine(
  'hbs',
  hbs.express4({
    partialsDir: __dirname + '/views/partials/',
    helpers: {
      __: function () {
        return i18n.__.apply(this, arguments);
      },
      __n: function () {
        return i18n.__n.apply(this, arguments);
      },
    },
  })
);

app.set('view engine', 'hbs');

app.use(express.json());
app.use(cookieParser());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(__dirname + '/public'));

i18n.configure({
  locales: ['zh', 'en'],
  defaultLocale: 'zh',
  cookie: 'locale',
  directory: __dirname + '/locales',
  directoryPermissions: '755',
  autoReload: true,
  updateFiles: true,
  objectNotation: true,
  api: {
    __: '__', //now req.__ becomes req.__
    __n: '__n', //and req.__n can be called as req.__n
  },
});
app.use(i18n.init);

app.use((req, res, next) => {
  if (req.cookies.locale === undefined) {
    res.cookie('locale', 'zh', { maxAge: 900000, httpOnly: true });
    req.setLocale('zh');
  }

  next();
});

app.get('/zh', (req, res) => {
  res.cookie('locale', 'zh', { maxAge: 900000, httpOnly: true });
  res.redirect('back');
});

app.get('/en', (req, res) => {
  res.cookie('locale', 'en', { maxAge: 900000, httpOnly: true });
  res.redirect('back');
});

app.use('/', indexRoutes);

app.listen(process.env.PORT || 3000, () =>
  console.log(`Server up on ${process.env.PORT || 3000}`)
);

Upvotes: 0

Ike Chang
Ike Chang

Reputation: 94

Check your header: accept-language.

According to the source code, defaultLocale will be used only when the following step goes through:

  1. queryParameter miss match
  2. cookie miss match
  3. headers['accept-language'] miss match

Upvotes: 2

mattyfew
mattyfew

Reputation: 163

This library is operating a bit funny to me. I added this middleware to my express server configuration and i18n started to behave as it should.

app.use(function (req, res, next) {
    var locale = 'en'
    req.setLocale(locale)
    res.locals.language = locale
    next()
})

Upvotes: 2

Peter Lyons
Peter Lyons

Reputation: 145994

This module looks in a lot of places for a locale setting. Have you carefully checked and double-checked none of those places are indicating "es" currently? Perhaps a stale cookie from a previous test you did? Try clearing your cookies.

Upvotes: 0

Related Questions