Creating multi language web app with i18n-2 in express - javascript

I created an express(node.js) website with two language with i18n-2 module and now i have a problem. i was thinking that if i change a new language except default language, all links in my web site will have /?lang parameter automatically! i18n-2 will do it or myself have to code this feature?
right now if i add /?lang=de by hand, it works but if i back to my websites root, it goes to defalult locale and that parameter removes from the url.
this is my configuration:
I18n.expressBind(app, {
locales: ['en', 'de'],
defaultLocale: 'en',
cookieName: 'locale',
extension: ".json"
});
app.use(function(req, res, next) {
req.i18n.setLocaleFromQuery();
req.i18n.setLocaleFromCookie();
next();
});

In order to perpetuate the selected language you need to install a package called cookie-parser:
npm install --save cookie-parser
Then attach it to the Express application as follows:
var app = require('express')(),
cookieParser = require('coookie-parser'),
i18n2 = require('i18n-2');
app.use(cookieParser());
i18n2.expressBind(app, {
locales: ['en', 'de'],
defaultLocale: 'en',
cookieName: 'locale'
});
app.use(function(req, res, next) {
if (req.query.lang) {
req.i18n.setLocaleFromQuery();
res.cookie(config.locale.cookie, req.i18n.getLocale());
} else {
req.i18n.setLocaleFromCookie();
}
next();
})
This way you can change the language through the lang query parameter and make it permanent using the cookie storage.

Related

cannot GET error 404 on reload?

my react router is working fine with dev env, this is what I did in webpack dev server:
historyApiFallback: {
index: 'index.html',
}
so in production mode I wanted to do the same, I did it in express like this:
const indexPath = path.join(__dirname, '../public/index.html')
const publicPath = express.static(path.join(__dirname, '../public'))
app.use('/public', publicPath)
app.use('/graphql', graphQLHTTP(async (req) => {
let { user } = await getUser(req.headers.authorization);
if(!user) {
user = 'guest'
}
return {
schema,
pretty: true,
graphiql: true,
context: {
user,
}
}
}));
app.get('/', function (_, res) { res.sendFile(indexPath) });
I did not change anything with react-router-dom so I am am assuming the error is in my express config. so what's the equivalent of historyApiFallback in production mode? below is my webpack bundle config:
output: {
path: path.join(__dirname, 'public'),
filename: 'bundle.js',
publicPath: '/public/'
},
in my html I reference the bundle like this:
<script type="text/javascript" src="/public/bundle.js"></script>
I think a have the right config but when I reload I get cannot GET Error 404?
You should add this line to your app:
app.get('*', function (_, res) { res.sendFile(indexPath) });
Or you should use this package better: https://github.com/bripkens/connect-history-api-fallback
You should read more about history mode:
To get rid of the hash, we can use the router's history mode, which leverages the history.pushState API to achieve URL navigation without a page reload:
When using history mode, the URL will look "normal," e.g. http://oursite.com/user/id. Beautiful!
Here comes a problem, though: Since our app is a single page client-side app, without a proper server configuration, the users will get a 404 error if they access http://oursite.com/user/id directly in their browser. Now that's ugly.
Not to worry: To fix the issue, all you need to do is add a simple catch-all fallback route to your server. If the URL doesn't match any static assets, it should serve the same index.html page that your app lives in. Beautiful, again!

Azure Mobile App node.js backend - Cannot get content of request

I want to use the easy api in Azure mobile app Node.js back-end server.
But I cannot get the content of the request after tried hard.
Can anyone tell me any possible things I lost ?
This is my api (myApi.js):
module.exports = {
"post": function (req, res, next) {
for (var k in req) {
console.log("%s: %j", k, req.k);
}
res.status(200).send('post');
}
}
This is my app.js:
var express = require('express'),
azureMobileApps = require('azure-mobile-apps');
var app = express();
var mobile = azureMobileApps({
// Explicitly enable the Azure Mobile Apps home page
homePage: true
});
mobile.tables.import('./tables');
mobile.api.import('./api');
mobile.tables.initialize()
.then(function () {
app.use(mobile); // Register the Azure Mobile Apps middleware
app.listen(process.env.PORT || 3000); // Listen for requests
});
I used Postman to send request.
Postman
And this is my console log, as you can see, everything of request is undefined.
params: undefined
query: undefined
headers: undefined
url: undefined
statusCode: undefined
body: undefined
...
You need to install body-parser module in your Mobile Apps server, config the body-parser middleware in the mobile app entrance app.js. Then you can use req.body to get the post body content.
You can try the following steps:
Login Kudu console site or Visual Studio Online editor of your mobile app server to modify scripts and run npm commands. Add body-parser module like "body-parser": "^1.13.1" under dependencies section in package.json file in your root directory. Run npm update to install the dependencies.
Add the stmt in app.js:
var bodyParser = require('body-parser');
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));`
Try the code snippet in your Easy APIs:
module.exports = {
"post":function(req,res,next){
console.log(req.body)
res.send(req.body)
}
};
In Postman, use x-www-form-urlencoded to post your data:
Try console.log("%s: %j", k, req[k]); instead.
The reason is variable k is a string. Therefore, to access a member by its key as string, you have to use the "array notation"

Cookies for Domain and its Subdomains in Node/ExpressJS

So what im attempting to do is to set a cookie on domain.com which is available to all subdomains *.domain.com. Im currently using Express 4.x and NodeJS.
At the moment I can set and get any Cookies on the main domain in my case its testing on a local environment via lvh.me:3000 (allowing for local subdomains)
This is bascially what my Express.js App looks like:
// Require all files (express,http,express-session,cookie-parser...)
var api = express()
// Cookie Parser
api.use(cookieParser());
api.use(session({
secret: 'yoursecret',
cookie: {
path: '/',
domain: '.lvh.me:3000',
maxAge: 1000 * 60 * 24, // 24 hours
},
resave: true,
saveUninitialized: true
}));
// CORS
api.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
next()
})
// View Engine
api.set('views', './api/views');
api.set('view engine', 'ejs');
api.disable('x-powered-by');
// Stylus
function compile(str, path) {
return stylus(str).set('filename', path);
}
api.use(stylus.middleware({
src: './app',
compile: compile
}));
// Serving Static Content
api.use(express.static('./app'));
// All Routes
require('../api/routes/test.server.routes.js')(api);
// Router
api.get('*', function(req, res) {
//res.cookie('remember', 1, { domain : "lvh.me:3000" });
res.render('index'); // Get all requests to Index. Angular takes over routing.
});
// Return Application
return api;
Cookies are set via Cookie Parser res.cookie('user', 'bobby'); which seem to be fine for going to lvh.me:3000/anything but for boddy.lvh:3000/anything the Cookies are empty.
Am I missing anything here, I thought Cookies would be available across all subdomains? I have read a few Articles/Posts on Stack Overflow but they all seem rather outdated. Any guidance or help is greatly appreciated.
On a side note if i set a cookie within express file it will be available through out the application. For Example:
// Router
api.get('*', function(req, res) {
res.cookie('user', 'jim'); // This can be accessed
res.render('index');
// Get all requests to Index. Angular takes over routing.
});
Any reason why? - This is in the most part because its being set on any/every view. So it still leaves me with the original question.
While setting cookie if your domain name mydomain.com it is not accessible by subdomains. You have to put leading dot (e.g .mydomain.com). In that case cookie will be shared across subdomains

Session management in Nodejs

I am beginner of NodeJS.And just started a simple project where I need a session management concept. So How to manage the session in NodeJS application.
In my project there is two file:- app.js and routes.js.
So where we add the session and how to add ??
app.js file :-
var express = require('express'),
app = express(),
path = require('path');
app.set('views', path.join(__dirname , 'views'));
app.engine('html', require('hogan-express'));
app.set('view engine', 'html');
app.use(express.static(path.join(__dirname,'public')));
require('./routes/routes.js')(express,app);
app.listen (3000 , function(){
console.log("working on the Port 3000");
});
and routes.js file :-
module.exports = function(express, app){
var router = express.Router();
router.get('/', function(req , res , next){
res.render('index',{title: 'Welcome'});
});
}
For the session management we need a middleware 'cookie-parser'.Previously it is the part of express but after express 4.0 and later it is a separate module.
So to access the cookie parser we need to install in our project as :
npm install cookie-parser --save
Then add this into your app.js file as :
var cookieParser = require('cookie-parser');
app.use(cookieParser());
Then we reqired session module. So first of all install the session module by :
npm install express-session --save
Then to enable the session. we add below code in app.js file.
app.use(session({secret:config.sessionSecret, saveUninitialized : true, resave : true}));
Then come to the routes.js file :-
Let us suppose there is a session variable favColor. Now using session set the color and get in the other page. the code is look like :-
router.get('/setColor', function(req , res , next){
req.session.favColor = 'Red';
res.send('Setting favourite color ...!');
});
router.get('/getColor', function(req , res , next){
res.send('Favourite Color : ' + (req.session.favColor == undefined?"NOT FOUND":req.session.favColor));
});
This is all about the session management.We can also learn more about the session :- This Reference
I dont suggest you try to build your own session and use https://github.com/expressjs/session instead which works with express well.
An update on 2019, using express-session 1.15.6 (From 1.5 there's no need to use cookie-parser, session can read and write the cookie directly.)
In app.js:
const app = express()
const session = require('express-session');
const options = {
name: 'foo', // Default is connect.sid
store: this.store, // Default is memoryStore, which is for dev only. Setup redis or memcached for prod
secret: 'bar', // Required, used to sign session id cookie
saveUninitialized: true, // Forces a session that is "uninitialized" to be saved to the store
resave: false, //Forces the session to be saved back to the session store
rolling: true //Force a session identifier cookie to be set on every response
};
// Session method will return a middleware function.
const middleware = session(options);
// Now we can make use of session in all the requests
app.use(middleware)
In routes.js or in any handler file created for specific route:
handler1(req, res, next) {
req.session.someField = 'foo';
// Use save method to update the store immediately, if there's other AJAX call pending.
req.session.save();
}
handler2(req, res, next) {
console.log(req.session.someField);
}
handler3(req, res, next) {
// we use delete operator here.
delete req.session.someField;
}

node.js : Getting browser language

Is there any way to get the browser language or something like that to know which language is client using?
I'm talking about node.js =)
thanks
As with any other HTTP server, the key here is the Accept-Language header that the browser sends with each request. See the HTTP 1.1 spec and the Accept-Language used for locale setting W3C FAQ page.
The actual code for reading the value of an HTTP varies depending on exactly which frameworks you're using ("vanilla" Node, Express, etc.).
If you happen to use the famous express server there exists middleware that does the job. request-language parses the Accept-Language header and returns the most preferred language for you:
var requestLanguage = require('express-request-language');
var cookieParser = require('cookie-parser');
var express = require('express');
var app = express();
app.use(cookieParser());
app.use(requestLanguage({
languages: ['en-US', 'zh-CN'],
cookie: {
name: 'language',
options: { maxAge: 24*3600*1000 },
url: '/languages/{language}'
}
}));
app.get('/', function(req, res, next) {
console.log(req.language); // 'en-US'
});

Categories