0
votes

So I've got my backend written in nodejs and I'm using i18next for internalization. I'm also using it on the frontend. The frontend's language is determined by the domain. e.g. es.domain.com is spanish and ja.domain.com is japanese etc.

On the backend the goal is to determine the users language via the domain origin and change the response language to their origin. Default will be english.

My question is,

When I change the language will it change the API default language or that request session language? i.e if user1 makes a request in Japanese that takes 5 seconds while user2 makes a request in English that takes 1 second right after user1. Will user1 accidentally get a response in English?

Sorry if the question is unclear/hard to understand. Please comment below and I'll try to reword it.

const i18n = require('i18next');

const express     = require('express');
const app         = express();
const port        = 3050;
const bodyParser  = require('body-parser');

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(require('express-useragent').express());

// Internationalization
i18n.init({
  resources: langResources,
  lng: "en",
  fallbackLng: "en",
  interpolation: {
    escapeValue: false
  }
}); 

// Cors
app.use(function(req, res, next) {

  // HERE's where I'll be detecting and changing the language
  i18n.changeLanguage('ja');
  console.log("i18n.t('test')",i18n.t('test',{count:1}));

  
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, auth-id, auth-token, x-csrf-token, _csrf");
  res.header('Access-Control-Allow-Methods', 'PATCH, POST, GET, DELETE, OPTIONS');
  next();
}); ```
1

1 Answers

0
votes

I realized I could just do a quick test of this like so.

I sent two requests. The first one had a sleep time of 5000ms and ja lang while the second one had a sleep time of 150ms and en lang.

test: async function(req){

      let user = req.query.user;
      let lang = req.query.lang;
      let time = req.query.time;

      // console.log("test 0Ro-> i18n.t('test')",i18n.t('test',{count:1}));

      i18n.changeLanguage(lang);
      console.log("user 1Ro:",user,"lang 1Ro:",lang);
      console.log("test 1Ro-> i18n.t('test')",i18n.t('test',{count:1}));
      await sleep(time)
      console.log("user 2Ro:",user,"lang 2Ro:",lang);
      console.log("test 2Ro-> i18n.t('test')",i18n.t('test',{count:1}));


    },

Unfortunately, ja language user returned in english which means the change language is not changing the session language but instead is changing the api language.

This is the answer to the question. However am still looking for a solution.

EDIT: Could not find the i18next solution so I just made my own. Here it is if you'd like to use it. Add express-session your project.

app.js - init

const {t} = require('./translations/i18n').i18n;

process.env.TZ = "Etc/GMT"

const express     = require('express');
const session     = require('express-session');
const app         = express();
const port        = 3050;
const bodyParser  = require('body-parser');

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(require('express-useragent').express());
app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}))

// Cors
app.use(async function(req, res, next) {

  let allowOrigins = [
    '(.*my-domain\.com)',
  ];

  if(Config.Env !== Environments.Production){
    res.header("Access-Control-Allow-Origin", "*");
  }else{
    res.header("Access-Control-Allow-Origin", Config.FrontEnd.Url);
    var origin = req.get('origin');
    console.log("origin",origin);
    for (let i = 0; i < allowOrigins.length; i++) {
      const allowOrigin = allowOrigins[i];
      if(origin.match(allowOrigin)){
        res.header("Access-Control-Allow-Origin", origin);
      }
    }
  }

  // example vars
  let user = req.query.user;
  let lang = req.query.lang;
  let time = req.query.time;

  // set language on session
  req.session.language = lang;


  console.log("user 1Ro:",user,"lang 1Ro:",lang);
  t(req,'test',{count: time});
  await sleep(time);
  console.log("user 2Ro:",user,"lang 2Ro:",lang);
  t(req,'test',{count: time});


  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, auth-id, auth-token, x-csrf-token, _csrf");
  res.header('Access-Control-Allow-Methods', 'PATCH, POST, GET, DELETE, OPTIONS');
  next();
});

all.js - your translations go here.

// import translation objects here. then add to tranlations object


const convertToSingularLocale = (messages, locale ) => {
  let singleLocale = Object.assign({}, messages)

  for (let property in singleLocale) {
    if (property === locale) {
      return singleLocale[property]
    } else if (typeof singleLocale[property] === 'object') {
      singleLocale[property] = convertToSingularLocale(singleLocale[property], locale)
    }
  }

  return singleLocale
}

const translations = {
  general: {
    languageAbbreviation: {
      de: "de",
      es: "es",
      en: "en",
      ja: "ja",
      fr: "fr",
      zh: "zh",
    },
  },
  test:{
    en: "TEST {{count}}",
    ja: "テスト {{count}}",
  }
}

const english = convertToSingularLocale(translations, 'en')
const japanese = convertToSingularLocale(translations, 'ja')

const langResources = {
  en: english,
  ja: japanese,
}

const availableLanguages = [
  { name: "English", nativeName:"English", code: "en" },
  { name: "Japanese", nativeName:"日本語", code: "ja" },
]

module.exports = {
  langResources: langResources,
  availableLanguages: availableLanguages,
} 

i18n.js - simple translator




const defaultLang = "en";
const {langResources} = require('./all');

const translate = (req,str,args) => {
  let validLang = false;
  let lang = req.session.language;
  for (var key in langResources) {
    if(langResources.hasOwnProperty(key)) {
      validLang = true;
      break
    }
  }
  if(!validLang){
    lang = defaultLang;
  }

  const sourceLang = langResources[lang];

  var keys = str.split(".");

  let source = sourceLang;
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    source = source[key];
  }

  let text = source;
  for (var key in args) {
    if(args.hasOwnProperty(key)) {
      text = text.replace("{{"+key+"}}", args[key]);
    }
  }

  return text;
}

const i18n = {
  translate: translate,
  t: translate,
} 

module.exports = {
  i18n: i18n,
}