How to make multilingual node.js app?!
Tags: javascript, multilingual, node, website
Published: 2020-12-09 17:03:34

Hello!

You are looking how to **easy** make **multilingual website** with seo urls? You are in right place! I will tell you about *"smws"* module.

So we are going to test this module, full test code can be found [on Github](https://github.com/docodern/smws/tree/main/test).
Check [npmjs.com](https://www.npmjs.com/package/smws) for documentation.

First off all, setup app.js. *"smws"* module work with Express, body-parser, cookie-parser and view engine (tested with Eta and ejs).
### Module install:
```cli
npm i express body-parser cookie-parser eta smws
```
### *app.js* example:
```javascript
const express = require('express'),
      cookieParser = require('cookie-parser'),
      bodyParser = require("body-parser"),
      smws = require("smws"),
      app = express();

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

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

app.listen(process.env.PORT || 3000, () => {
   console.log('Server running on port 3000');
});
```
### Next step, we need to configure *"smws"*:
```javascript
smws.config({
    languages: ['en','ru'],
    defaultLang: 'en'
});
```
So, I will use two languages and default is 'en'. I don't need to add other options in config because they can stay with default values.

### Language switcher

To change language from front-end setup view engine templates. We need form to send chosen language to the server:
```html
<!-- action will be "/<%= smws.lang %>/language" if you use ejs -->
<!-- I'm using eta view engine -->
<form action="/<%= it.smws.lang %>/language" method="post">
    <button class="en-button" type="submit" name="lang" value="en">EN</button>
    <button class="ru-button" type="submit" name="lang" value="ru">RU</button>
</form>
```
To receive this language changes, add to your *app.js*:
```javascript
app.post('/:lang/language', (req,res)=>{
    smws.switcher(req,res);
});
```
`smws.switcher(req,res);` controles language changes.

### GET requests with smws

Next we add our paths to *app.js*:
```javascript
app.get('/', function (req, res) {
    smws.run(req, res, {
        page: 'index'
    });
});

app.get('/:lang', function (req, res) {
    smws.run(req, res, {
        page: 'index'
    });
});

app.get(smws.split('/:lang/:category'), function (req, res) {
    smws.run(req,res,{
        page: 'category',
        useParams: ['lang', 'category']
    });
});
```
`smws.split('path')` use for your paths where you need to translate and control **more** than only language parameter.
`smws.run(req,req,{options});` use to response your template and control parameters. `page: ` option is mandatory.

I'm using two paths for homepage to cover main url like `domain.com` and with language param like `domain.com/en`.

When user **first time visit your main page**, it will be rendered in default language which chosen in `smws.config({...`.

If someone visit your website **using** some **url**. For example click somewhere `domain.com/ru/kategoriya`, page will be rendered in `ru` language, so chosen from params.

### Language files

In the end we need language files. By default *"smws"* use *.json* files from *"languages"* folder in root directory. But you can change it in:
```javascript
smws.config({
...
langDir: 'your/dir/name'
...
});
```

Language file names must be same with your website languages. In this tutorial *en.json* and *ru.json*.
Example:
```
//en.json
{
    "smws": {
        
            "category": "category",
            "lang": "en"
        
    },
    "hello": "This is main page in 'EN'"
}
```
```
//ru.json
{
    "smws": {
        
            "category": "kategoriya",
            "lang": "ru"
        
    },
    "hello": "Главная страница на 'RU'"
}
```

So in the end we get:
 - website with changeable languages,
 - can set SEO friendly urls,
 - only one `app.get(...` for all languages,
 - no page duplicates like `domain.com/ru/kategoriya` and `domain.com/ru/category`. Last one will send 404 status because param `:category` does not match `:lang` param "ru".

Thank you for attention! Hope this will be helpful for someone!