How to add the locale (“en”, “fr”, …) at the root of the URL in VueJS? There are several ways of doing it, so let’s review them.
We will try to achieve something like that :
mysite.com/en/user/john
Please note that we will be using Vue Router & Vue-I18n for internationalization. You can still read this article if you don’t use these Vue plugins. It won’t stop you from getting the big picture and implementing these solutions in your app, but I strongly advise you to use these plugins anyway.
Project setup
Vue-I18n
First, install Vue-I18n. We’ll use npm :
npm install vue-i18n
Then create a translations
directory inside src
. The newly created folder will have an index.js
file containing Vue-I18n’s configuration. We will set the plugin so it lets the browser decide what the default language should be :
|
|
Vue Router
For the moment this is pretty straightforward. Install the router with npm :
npm install vue-router
Create a folder called router
and inside of it an index.js
file containing the following configuration :
|
|
Link it all together
Now, inside main.js
, you need to have your app configured that way :
|
|
Adding the locale in the URL
Go back to the router’s configuration file. We want to tell the router to redirect the users to /:lang (where :lang
can be “fr” or “en” in our example) whenever they try to access / (the base route).
|
|
For the moment, the Home
component will just contain some simple text provided with the translation:
|
|
The Home component will be displayed but the URL won’t be changed. That’s because the router doesn’t know what to do with the lang
parameter. So we’ll make use of the beforeEnter
navigation guard to tell it what value to give that parameter:
|
|
Now whenever the user wants to access the base of the site, he’ll be redirected to /:lang where :lang is the default language. Also, if you add some translatable text in your User component, the text will be translated even if you switch the locale in the URL to fr. Try it !
Using nested routes
But that’s not enough. We want our app to be more than just a single page that translates “Welcome” into french. There are many ways to structure an app. So let’s see how we would configure our router in a real world application.
In this first case, let’s pretend our app uses nested routes, like that:
/profile /posts
+------------------+ +-----------------+
| Home | | Home |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
The idea is that Home
will contain other components, like a menu that will be shared with Profile
and Posts
. Of course those last two components can also contain their own nested routes.
So, how do we do this? By providing our lang
route with children:
|
|
Do not forget to add a router-view tag in the Home component…
|
|
…and to add, of course, the two new components:
|
|
|
|
Let’s add the translation :
|
|
The app now works !
So what about sites that do not use nested routes ?
In the very simple app we’ve just created, the user and the posts pages are both children of the Homepage. In lots of cases, we may want to make our pages more distinct, like this for example :
/ /posts
+------------------+ +-----------------+
| Home | | Posts |
| | | |
| | +------------> | |
| | | |
| | | |
+------------------+ +-----------------+
/user
+-----------------+
| User |
| |
+------------> | |
| |
| |
+-----------------+
It’s actually quite simple. We’ll have to remove the children array, and set up all the routes as siblings. Also, we’ll use the beforeEach()
safeguard, and it will be applied to the router
variable.
|
|
You can have access to the source code from the Github repository.