Open fourpixels opened 8 years ago
ok, got it - adding skipHeaderChecks
and/or silently ignoring their absence won't be a big deal... thank you for spotting
The problem here is that my browser always sends Accept-Language:en-US,en;q=0.8,bg;q=0.6,fr;q=0.4
no matter what. And therefore, if you browse through the code you'll see that it always ends in finding that language in the available languages and sets it as the language to use.
By I am setting the defaultLocale
to something else! Which means that if I do not send query param nor cookie, I should be using the default one, right? But it's not happening, because of browser headers, which I cannot control.
What bothers me is that those headers are sent because of OS configuration like region or language, which I cannot control. And I think they are sent almost always, no matter what. Which makes defaultLocale
useless if you have that accept-language in your list of languages.
My use case is that I want the default language to be Bulgarian, but still support English. But most of the users in that country use OS in English, and therefore end up seeing the site in English, despite not providing query param for that. The only option is to always send query parameter, even for the default values, which I dislike :)
Hope that makes sense now :)
People with Simulator setups used to use a Cookie to persist language setting... Should help until next Release.
Von meinem iPhone gesendet
Am 09.04.2016 um 08:05 schrieb fourpixels notifications@github.com:
The problem here is that my browser always sends Accept-Language:en-US,en;q=0.8,bg;q=0.6,fr;q=0.4 no matter what. And therefore, if you browse through the code you'll see that it always ends in finding that language in the available languages and sets it as the language to use.
By I am setting the defaultLocale to something else! Which means that if I do not send query param nor cookie, I should be using the default one, right? But it's not happening, because of browser headers, which I cannot control.
What bothers me is that those headers are sent because of OS configuration like region or language, which I cannot control. And I think they are sent almost always, no matter what. Which makes defaultLocale useless if you have that accept-language in your list of languages.
My use case is that I want the default language to be Bulgarian, but still support English. But most of the users in that country use OS in English, and therefore end up seeing the site in English, despite not providing query param for that. The only option is to always send query parameter, even for the default values, which I dislike :)
Hope that makes sense now :)
— You are receiving this because you commented. Reply to this email directly or view it on GitHub
Oh no worries! :) As I said I've already hacked it and it's now working like a charm. It's not that bad as working only with headers is not suggested by the online gurus anyways.
Providing different content solely based on cookie is really bad fore SEO, so I will just wait for the next release :) Good luck!
apropos seo... consider hacking some middleware and switch with setLocale based on an url segment, like so:
router.all('/:lang/*', function(req, res, next){
i18n.setLocale(req, req.params.lang);
next();
});
Great idea! I was thinking of something similar, but not quite. I'll just have to check if there's that specific segment or not. I want the default language to have clear urls, and only the other ones to have additional segments/parameters or whatever. I can optionally switch to subdomains for each language.
The only things that bothers me is that there might be something in the url similar to any of the languages (this is only hypothetical but still), but I can live with that for now.
Anyway, thanks for the idea - sounds really great!
@mashpie For some reason rotuter.all
not working for me, only this:
app.all('/:lang/*', function(req, res, next){
//i18n.setLocale(req, req.params.lang);
i18n.setLocale([req, res.locals], req.params.lang);
next();
});
But the problem is that everything is translated, except the {{{body}}}
(I use express-handlebars). I've got 404 error.
I'm placing this in my app.js, before every other route. I call the routes with:
app.use('/', require('./routes/index'));
app.use('/blog', require('./routes/blog'));
app.use('/category', require('./routes/blog-category'));
app.use('/tag', require('./routes/blog-tag'));
app.use('/contact', require('./routes/contact'));
well that totally depends on your express setup, call your express-router router
, app
, server
or pony
...
your 404 will most probably result from unproper nesting of routes. Please refer to http://expressjs.com/en/guide/routing.html esp the very last section:
var birds = require('./birds');
...
app.use('/birds', birds);
The app will now be able to handle requests to /birds and /birds/about, as well as call the timeLog middleware function that is specific to the route.
So I Guess you need to wrap all of your routes into a
app.all('/:lang/*', function(req, res, next){...});
app.use('/:lang', require('./routes/all'))
all.js
containing all deeper urls, like
app.use('/', require('./routes/index'));
app.use('/blog', require('./routes/blog'));
app.use('/category', require('./routes/blog-category'));
app.use('/tag', require('./routes/blog-tag'));
app.use('/contact', require('./routes/contact'));
resulting in effectively changing resources to
I'd love to gist an example but need to quit for today...
I changed the improper nesting to the recommended method, and it's the same (see /contact
):
https://github.com/DJviolin/lantosistvan/blob/0c0ba696ac186286cbcf08405f98aee40f7e37ba/app.js
Setting the translation only with a cookie works like a charm. But I want a SEO friendly translation if it's possible.
https://github.com/DJviolin/lantosistvan/blob/0c0ba696ac186286cbcf08405f98aee40f7e37ba/app.js#L166 should read
app.use('/:lang/contact', contact);
to make URLs work like:
you might also consider https://github.com/mashpie/i18n-node#i18n__l to get completly localized urls
Thank You! So I have to init the routers with:
app.use('/contact', contact);
app.use('/:lang/contact', contact);
Probably I will mix this with cookies. My only problem is if someone clicks on a link than the query.param
goes away from the URL. My links is hardcoded into the handlebars templates. Is there a way to update them when someone clicking on the logo I want to arrive from /en/contact
to /en
on the home.
Another problem is for the index translation /en
doesn't work, just only /en/
. The code is:
app.use('/', index);
app.use('/:lang', index);
Here is the refactored app.js: https://github.com/DJviolin/lantosistvan/blob/857049533b09411f9da92c473c0a68f0636c0dc8/app.js
Come on pal, this is for stackoverflow, not here :)
@DJviolin please refer to expressjs docs - routing issues are not i18n related - try searching for "Enable strict routing" on http://expressjs.com/en/4x/api.html You should find express.Router([options]) - or check out https://github.com/ericf/express-slash
@mashpie Thank You!
you can use
app.use(function(req, res, next){ i18n.setLocale(req.query.lang); next(); });
Hi there, I've recently started using your module and it just worked out of the box, which is amazing!
I just have one basic problem which drives me crazy. The
init
function uses headers as last resort to find user's locale. Which, used alone, is not quite safe and somehow makesdefaultLocale
meaningless.This is my setup:
And let's say I use this schema for switching languages:
But then I understand that my browser sends
Accept-Language:en-US,en;q=0.8,bg;q=0.6,fr;q=0.4
, so mydefaultLocale
is just skipped and I get the page in English, despite NOT providing a language parameter.I think there should be a way to disable header check, just like there is a way to disable both
query
andcookie
lookup (by not providing parameters for them). Relying on user settings in order to get specific language alone seems like very dangerous game, and it's a highly recommended no-no.I think there could be a parameter if headers check should be done, set to
true
by default ;) For now, I'm shamelessly short-term fixing my issue with: