How to architect multilanguage routes with i18n

I’m looking for advice on how to structure a multi language application using ember-i18n. I wasn’t able to find many resources on this so any guidance would be greatly appreciated!

Routes should be localized and prefixed with the locale (unless it’s the default). Like this:

  • news
  • es/noticias

The API can be namespaced with the locale as such:

  • api/news/5
  • es/news/5
  • /news/5?locale=es

I thought about nesting all routes in a:

this.route('locale', {path: ':locale}, function () { this.route('music'); }

… which would allow you to localize and redirect on the language route. But when you for instance transition to the route en.news the path would not end up being /news/ but /en/news/ (with locale). I need the default locale (en in this case) to not be prefixed.

1 Like

I imagine in most cases that only locale will be used in the lifetime of an app for the user. If the user needs to switch locales, might just be worth it to teardown the app anyway since you would need to load new translations.

Anyway, here is how you can register routes by using translations:

// app/instance-initializers/register-i18n-routes.js
import Ember from 'ember';

export default {
  name: 'register-i18n-routes',
  initialize(instance) {
    let i18n = instance.container.lookup('service:i18n');
    let Router = instance.container.lookupFactory('router:main');

    Router.map(function() {
      this.route('books', { path: i18n.t('route.books') });
      this.route('movies', { path: i18n.t('route.movies') });
    });
  }
};

If you can preload the application with translations and the locale code that could be used to set the router’s rootURL, I think that would satisfy your requirements. This will give you /en/movies without ever having to worry about the root URL anywhere in your application and enable not sending down translations for every locale to your app…

I’ve done this in a number of apps, but I haven’t built an addon out of it since every implementation varied in requirements.

Thank you! I had to do add the extra .string from SafeString, otherwise it works very nicely.

Router.map(function () {
	this.route('music', {path: i18n.t('route.music').string});
});

To set the rootURL, I have a regular expression that guesses the locale from the URL and if it’s not the default locale, it sets it:

Router.reopen({rootURL: `/${newLocale}/`});

As a bonus, this repository looks interesting https://github.com/kellyselden/ember-i18n-route although it’s missing some documentation.

I know it’s been a while, but for the completness I add this.

It is possible to have multiple names for one route.

this.route(‘books’, { path: ‘books’ });

this.route(‘books’, { path: ‘libros’ });

Then you can internally redirect the user to the correct route by specifying the name in the “transitionTo” calls and the link-to helper also supports this.

1 Like

Again reviving an old topic, @gerrit do you have an example of how you redirect the user here? In my attempt it seems only the route that was defined last (in your example with the path:' libros' ) is can be loaded. The other one just gets forwarded so I’m at a loss on how to prevent that. Thanks in advance!