AngularJS UI router append/force language code if not there

Issue

I have a scenario where my app’s first route is the language code, meaning all the the app’s routes are dependent on the language code, my $stateProvider looks something like this:

$stateProvider
    .state('app',{
        url: '/:languageCode',
        templateUrl:'./views/routes/app.html',
        controller:'appController',
        abstract: true,
    })
    .state('app.home',{
        url:'/',
        templateUrl:'./views/routes/home.html',
        controller:'homeController',
    })
    .state('app.products', {
        url:'/product',
        abstract: true,
    })
    .state('app.products.selectedProduct', {
        url: '/:productId',
        templateUrl:'./views/routes/productPreview.html',
        controller:'previewController'
    });

Final routes examples:

http:localhost:3000/de
http:localhost:3000/it/products
http:localhost:3000/en/products/some-product-id

I want to be able to route the app with the relevant language code case it’s not there, so if a user navigates to http:localhost:3000/products the app will append the missing langCode with either the saved language that the user selected or the default language of the app, (i.e: http:localhost:3000/it/products).

How can this be achieved ?

Solution

After some research, I was able to achieve that using the $urlRouterProvider‘s rule and otherwise methods

In the rule method, I check if the url path contains the language code and append if it doesn’t.
The otherwise method is simply used to navigate to home if the route doesn’t exist.

The implementation goes as follows:

    // Force urls with lang code
    $urlRouterProvider.rule(function ($injector, $location) {
        //what this function returns will be set as the $location.url
        let path = $location.path(),
            langCode = path.split('/')[1], // 0 is "" cuz path begins with /
            // get lang for code
            lang = window.globals.SUPPORTED_LANGS.find((lang) => lang.code === langCode.toLowerCase());
        if (!lang) {
            // Return path with lang code
            return `/${localStorage.getItem(enums.localStorageKeys.preferredLanguage) || 'it'}${path}`;
        }
        // otherwise return nothing so no state changes will not occur
    });
    // Default route case doesn't exit
    $urlRouterProvider.otherwise(function ($injector, $location) {
        return `/${localStorage.getItem(enums.localStorageKeys.preferredLanguage) || 'it'}/`
    });

Answered By – Samer Murad

Answer Checked By – Marilyn (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.