 <p>Your way is wrong. if you have view for every language, then what's the point to use i18n? </p> <p>You can just get </p> <pre><code>?lang= </code></pre> <p>value and send <code>res.render ( '/' + req.query.lang + '/contact.html').</code></p> <p><em>Try way is</em></p> <pre><code>-locales --en.json --nl.json -view --cabinet.html --main.html </code></pre> <p><strong>app.js</strong></p> <pre><code>i18n.configure({ locales: ['en', 'nl'], directory: __dirname + '/locales', defaultLocale: 'nl', updateFiles: false, objectNotation: true }); app.use(i18n.init); app.use(function (req, res, next) { console.log(i18n); if (req.query.lang != undefined &amp;&amp; i18n.locales.indexOf(req.query.lang) &gt;= 0) { i18n.setLocale(req.query.lang); }else{ i18n.setLocale(i18n.defaultLocale); } next(); }); </code></pre> <p><strong>en.json</strong> example</p> <pre><code>{ "cabinet": { "menu": { "title": "Menu", }, "dashboard": { "title": "Dashboard" }, "statistic": { "datePeriod": "Date period", "choose": "Choose", } }, "main": { "title": "Main", "body": { "hi": "Hi everyone!" } } </code></pre> <p>same for nl.json</p> <p><strong>main.html</strong></p> <pre><code> I use Swig template &lt;html&gt; &lt;head&gt; &lt;title&gt;{{ translate.title }}&lt;/title&gt; &lt;/head&gt; &lt;body&gt; {{ translate.body.hi }}!! &lt;/body&gt; &lt;/html&gt; </code></pre> <p><strong>router.js</strong></p> <pre><code>router.get('/main', function(req, res, next) { res.render('/main', { title: '...', menu: '...', translate: res.__('main') }); }); router.get('/cabinet', function(req, res, next) { res.render('/cabinet', { title: '...', menu: '...', translate: res.__('cabinet') }); }); </code></pre>