Aspnetcore-angular-universal: How to get navigator.language / navigator.languages server side?

Created on 14 Feb 2018  路  5Comments  路  Source: TrilonIO/aspnetcore-angular-universal

I'm trying to localize my application and set application language depends on user's browser language.
It is possible to get it (get values of navigator.language / navigator.languages) on the server to set & load proper localization?

Most helpful comment

In Home/Index:

var preRenderModel = new PreRenderModel
{
    L10n = new L10nInitData
    {
        Language = Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName,
    },
    Location = location,
};
var prerenderResult = await Request.BuildPrerender(preRenderModel);
ViewData["TransferData"] = prerenderResult.Globals["transferData"]; // our transfer data set to window.TRANSFER_CACHE = {};

Register in the client app:
In boot.server.ts:

const setupOptions: IEngineOptions = {
    appSelector: '<app-root></app-root>',
    ngModule: AppModule,
    request: params,
    providers: [
        { provide: 'LANG', useValue: params.data.preRenderData.l10n.language }
    ]
};

In app.module.browser.ts:
```providers: [
{ provide: 'LANG', useValue: window['TRANSFER_CACHE'].initData.l10n.language }

Anywhere you're gonna  use it, inject in constructor:

constructor(@Inject('LANG') lang: any)
```

All 5 comments

I had the same task and I did the following:

  • On the server side I determine user's language with asp.net core out of the box implementation (UseRequestLocalization in Startup.cs)
  • In /Home/Index action I get user's language from the Thread (Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName) and put it to prerenderResult to pass to the client app.

This way I'm sure I have the same language both on the server and the client sides. (I need to be able to override the language determined from accept-language header and use that language both on the server and the client side)

@andreydil Can you please give me an example how to put TwoLetterISOLanguageName to prerenderResult and how to read it in the angular app?

Thank you.

In Home/Index:

var preRenderModel = new PreRenderModel
{
    L10n = new L10nInitData
    {
        Language = Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName,
    },
    Location = location,
};
var prerenderResult = await Request.BuildPrerender(preRenderModel);
ViewData["TransferData"] = prerenderResult.Globals["transferData"]; // our transfer data set to window.TRANSFER_CACHE = {};

Register in the client app:
In boot.server.ts:

const setupOptions: IEngineOptions = {
    appSelector: '<app-root></app-root>',
    ngModule: AppModule,
    request: params,
    providers: [
        { provide: 'LANG', useValue: params.data.preRenderData.l10n.language }
    ]
};

In app.module.browser.ts:
```providers: [
{ provide: 'LANG', useValue: window['TRANSFER_CACHE'].initData.l10n.language }

Anywhere you're gonna  use it, inject in constructor:

constructor(@Inject('LANG') lang: any)
```

Thank you very much. This code helped me a lot!

Here is an article how to detect browser's language in asp.net core:
http://gunnarpeipman.com/2017/03/aspnet-core-simple-localization/

Plus the code you wrote = excellent result!

Great write up @andreydil ! 馃挴

One additional thing I would add, is to try not to use String as a provide type. Use the InjectionToken (passing it the string name), and that way there will never be a mix-up if there are identically named Tokens, since they come from different file import sources.
Just a helpful tip :)

import { InjectionToken } from '@angular/core';

export const LANG = new InjectionToken<string>('LANG');
Was this page helpful?
0 / 5 - 0 ratings