Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serve effective AOT language Angular app in Firebase hosting?

I have an angular 4 app hosted by Firebase hosting service with a custom domain (ex: www.something.com that redirects to firebase url). I used i18n internationalization and my question is: Which is the best way to serve the correct compiled app depending the user nation? In this moment there's only the standard --aot en online and I'd like to serve the --aot it version if someone comes from Italy for example.

Thanks

like image 459
Danilo Dughetti Avatar asked Dec 12 '17 22:12

Danilo Dughetti


2 Answers

I also ran into the same problem. I accomplished it by making changes to the firebase.json Hosting attribute

{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "redirects": [
      {
        "source" : "/",
        "destination" : "/en",
        "type" : 301
      }
    ],
    "rewrites": [
      {
        "source": "/en/**",
        "destination": "/en/index.html"
      },
      {
        "source": "/es/**",
        "destination": "/es/index.html"
      },
      {
        "source": "/fr/**",
        "destination": "/fr/index.html"
      }
    ]
  }
}

Hope this helps you!

like image 128
yashmurty Avatar answered Nov 02 '22 10:11

yashmurty


I had the same problem but couldn't find a solution. So I created another approach in which I would use i18n internationalization. This way I could use multi language in a single build.

I'm not sure if this is the best way, but this is mine:

I created a very simple service which provides the window. Provide it as root!

function _window(): any {
  // return the global native browser window object
  return window;
}

@Injectable()
export class WindowRef {
  get nativeWindow(): any {
    return _window();
  }

  public ln = 'en'; //default language


  constructor() {
    try {
      if (!isNullOrUndefined(this.nativeWindow.navigator.language) && this.nativeWindow.navigator.language !== '') {
        let lang = this.nativeWindow.navigator.language;
        if (lang.indexOf('-') >= 0) {
          lang = lang.split('-')[0]; //replace en-us with en.
        }
        this.ln = lang;
      }
    } finally {
    }
  }
}

For the defaut angular pipes I created a simple wrapper:

@Pipe({name: 'datepipe', pure: true})
export class MyDatePipe extends DatePipe implements PipeTransform {
  constructor(private win: WindowRef) {
    super(win.ln);
  }

  transform(value: any, pattern?: string): string | null {
    return super.transform(value, pattern);
  }
}

For text I created a very simple pipe:

@Pipe({name: 'translate'})
export class TranslationPipe implements PipeTransform {
  constructor(private translationService: TranslationService) {

  }

  transform(value: string) {
    return this.translationService.getTranslation(value);
  }
}

The pipe uses this translation service:

@Injectable()
export class TranslationService {
  lng: string = 'en';

  nl: Array<KV> = [
    {key: 'Hello', value: 'Hallo'},
  ];

  languages = [
    {key: 'nl', value: this.nl}

  ];

  constructor() {
    if (!isNullOrUndefined(navigator.language)) {
      this.lng = navigator.language;
    }
    if (this.lng.indexOf('-') >= 0) {
      this.lng = this.lng.split('-')[0];
    }
  }

  getTranslation(key: string): string {
    return this.findByKey(this.findByKey(this.languages, this.lng), key) || key;
  }

  private findByKey(list: { key, value }[], key: string): any {
    if (!isNullOrUndefined(list)) {
      for (let i = 0; i < list.length; i++) {
        if (list[i].key === key) {
          return list[i].value;
        }
      }
    }
    return undefined;
  }
}

export class KV {
  key: string;
  value: string;
}

I hope you'll find this usefull

like image 34
Robin Dijkhof Avatar answered Nov 02 '22 10:11

Robin Dijkhof