Dynamically load different css files in angular2 application based on user's language

Sobhan picture Sobhan · Jan 12, 2017 · Viewed 11.4k times · Source

I have an Angular2 application and it need to support multiple languages. Some of these languages may be RTL (i.e Persian) and some will be LTR (i.e. English). Apart from localizing strings, I need to style my components based on the direction of the language.

Now using this helper, I can have two separate files (i.e. app-rtl.scss & app-ltr.scss) which both import a single scss file (i.e. app.scss) which allows me to write my scss code in one place and automatically output two files; one for each direction.

The problem is now I need to somehow reference the suitable css file based on the user's language. So if the user's language is English then I should have <link href="app-ltr.css" rel="stylesheet"> in the header and if it's RTL, <link href="app-rtl.css" rel="stylesheet">. Furthermore I want to add bootstrap to my project and that also has two different output files for LTR and RTL.

Is there any clean way to achieve this functionality?

What I've tried:

I've create two dummy component (one for LTR and one for RTL) without any template and then assign the respective scss file with styleUrls and set encapsulation: ViewEncapsulation.None so that it becomes a global style. Then I initialize both of them in my root component template with an *ngIf and check if the language is LTR or not.

This would work on the first page load because only one component (let's say component LTR) is active, but as soon as you change the language (i.e the second component (RTL) becomes active and thus LTR is removed) then the styles associated with the LTR stays on the page and is not removed. So then you have both RTL and LTR styles on your page which is not intended.

Answer

Milad picture Milad · May 19, 2017

You'd need to conditionally add or remove the style from the browser:

to add

loadIfNot(url,cssId){

     if (!document.getElementById(cssId)){
        var head  = document.getElementsByTagName('head')[0];
        var link  = document.createElement('link');
        link.id   = cssId;
        link.rel  = 'stylesheet';
        link.type = 'text/css';
        link.href = url;
        link.media = 'all';
        head.appendChild(link);
    }else{
        document.getElementById(cssId).disabled = false;///i fit's already there, enable it
    }

  }

and for remove

 disable(cssId){
     document.getElementById(cssId).disabled = true
 }

Disable and Enable is because browser tends to cache your styles, and in order to make them enable or disable, you'd change that attribute