Search code examples
angularangular-universalangular-lazyloadingangular-localize

loading additional scss files or code based on the chosen locale


I'm writing an angular 11 universal application with localization.

what I'm trying to achieve is to be able to load more scss files based on the locale chosen.

so for example if the user chose Hebrew it will add styles-he.scss that added direction:rtl.

I googled a lot and basically all say the same as this url: https://juristr.com/blog/2019/08/dynamically-load-css-angular-cli/

that I need to add the new style in my angular.json so it will be lazy loaded:

 "styles": [
          "src/styles.scss",
          {
            "input": "src/styles-he.scss",
            "bundleName": "hebrewStyle",
            "inject": false
          }
   ...

and then I should create a loadStyle component in app.component.ts:

loadStyle(styleName: string) {
    const head = this.document.getElementsByTagName('head')[0];

    let themeLink = this.document.getElementById(
      'client-theme'
    ) as HTMLLinkElement;
    if (themeLink) {
      themeLink.href = styleName;
    } else {
      const style = this.document.createElement('link');
      style.id = 'client-theme';
      style.rel = 'stylesheet';
      style.href = `${styleName}`;

      head.appendChild(style);
    }
  }

and execute loadStyle('styles-he.scss') whenever I want

ahhh.. actually the tutorial talked about css, don't know if scss would work. probably I must use css in this method.

the thing is that I expected that there would be of a more angular way to include these style files based on countries. didn't quite understand when I execute this function and how do I know which language it is.

this is my locale configuration in angular.json

 "i18n": {
        "sourceLocale": "en",
        "locales": {
          "he": {
            "translation": "src/locale/messages.he.xlf",
            "baseHref": "he/"
          }
        }
      },

so in general I'm lost in what's the proper way to add more styles based on the locale chosen.


Solution

  • ok so i found a cool solution on stackoverflow for this.

    i learned how to inject locale from How To Use LOCALE_ID In Angular i18n Router Module and the cool method from here:

    change Style sheet when different language is selected.

    i'm actually gonna have one file of css, but i can determine the language from the css file itself, which is actually a better solution then having separate files.

    so this is what I did:

    in the app.component.ts i did this:

    export class AppComponent implements OnInit, OnDestroy {
     constructor(@Inject(LOCALE_ID) private locale: string,....)
    
     ngOnInit(): void {
       document.documentElement.setAttribute('lang', this.locale);
     }
    }
    

    I injected the locale, and i set a lang attribute on the document with the locale value

    then in each scss style file for a component, i can add this:

    :host-context([lang="he"]){ ... }

    I learned it from here: Access body lang in SCSS in Angular 6

    this way i'm not loading any css files dynamically with loadStyle function that i posted on my question and i don't need to lazy load anything.

    this answer was updated after testing it on angular 15