Skip to content

Angular recognize only the default lang in SSR. #163

@bcentdev

Description

@bcentdev

I'm submitting a ... (check one with "x")

[x] bug report => Search github for a similar issue or PR before submitting
[ ] feature request => Please check if similar feature request does not exist
[ ] support request => Suggested place for help and support is [stackoverflow](https://stackoverflow.com/), search for similar question before posting

Description

Hello, I have an Angular application with Angular Universal, localize-router and ngx-translate installed. When I navigate in the client side of the website, the languages are working well. I have the default language (es) configured to be hidden in the url and english as secondary language. For example:

es => http://localhost:4000/quotation
en => http://localhost:4000/en/quotation

The problem is that if I deactivate Javascript and force to load the server side of the website, only It works the default language.

es => http://localhost:4000/quotation
en => http://localhost:4000/en/quotation

Even If I try to put the default language in the url, It works too:

es => http://localhost:4000/es/quotation

Node returns me this error in console:

Error: Cannot match any routes. URL Segment: 'en/quotation'

It's like the localize is not well configured but I think that I configured similar to the client side.

🔬 My files

Dependencies of package.json


{
  "dependencies": {
    "@angular/animations": "^7.2.10",
    "@angular/common": "^7.2.12",
    "@angular/compiler": "^7.2.12",
    "@angular/core": "^7.2.12",
    "@angular/forms": "^7.2.12",
    "@angular/http": "^7.2.12",
    "@angular/platform-browser": "^7.2.12",
    "@angular/platform-browser-dynamic": "^7.2.12",
    "@angular/platform-server": "^7.2.12",
    "@angular/router": "^7.2.12",
    "@bugsnag/js": "^6.0.0",
    "@bugsnag/plugin-angular": "^6.0.0",
    "@ng-bootstrap/ng-bootstrap": "^4.1.1",
    "@nguniversal/express-engine": "^7.1.1",
    "@nguniversal/module-map-ngfactory-loader": "^7.1.1",
    "@ngx-translate/core": "^11.0.1",
    "@ngx-translate/http-loader": "^4.0.0",
    "bootstrap": "^4.3.1",
    "classlist.js": "^1.1.20150312",
    "compression": "^1.7.4",
    "cookie-parser": "^1.4.4",
    "core-js": "^2.6.5",
    "express": "^4.16.4",
    "font-awesome": "^4.7.0",
    "jquery": "^3.3.1",
    "localize-router": "^2.0.0-RC.2",
    "localize-router-lazy-universal-module-loader": "^1.0.1",
    "material-design-icons": "^3.0.1",
    "ngx-cacheable": "^1.1.6",
    "ngx-cookie-service": "^2.1.0",
    "ngx-device-detector": "^1.3.5",
    "ngx-owl-carousel-o": "^1.1.1",
    "rxjs": "^6.4.0",
    "rxjs-compat": "^6.4.0",
    "standard-version": "^4.4.0",
    "tslib": "^1.9.0",
    "web-animations-js": "^2.3.1",
    "zone.js": "^0.8.29"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^0.13.8",
    "@angular/cli": "^7.3.8",
    "@angular/compiler-cli": "^7.2.12",
    "@angular/language-service": "^7.2.12",
    "@types/jasmine": "^2.8.16",
    "@types/jasminewd2": "~2.0.3",
    "@types/jquery": "^3.3.29",
    "@types/node": "^8.10.45",
    "angular-router-loader": "^0.8.5",
    "awesome-typescript-loader": "^5.2.1",
    "codelyzer": "~4.5.0",
    "jasmine-core": "~2.99.1",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~3.1.1",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "^2.0.5",
    "karma-jasmine": "~1.1.2",
    "karma-jasmine-html-reporter": "^0.2.2",
    "nucleus-styleguide": "^1.1.1",
    "protractor": "~5.4.0",
    "ts-loader": "^5.3.3",
    "ts-node": "~7.0.0",
    "tsconfig-paths-webpack-plugin": "^3.2.0",
    "tslint": "~5.11.0",
    "typescript": "~3.1.6",
    "webpack-cli": "^3.3.0"
  }
}

NgModule of app.module.ts


@NgModule({
	declarations: [
		AppComponent,
		CalendarModalComponent,
		TimeSlotModalComponent,
		DiscountModalComponent
	],
	imports: [
		BrowserModule.withServerTransition({ appId: 'frontend' }),
		AppRoutingModule,
		BrowserAnimationsModule,
		CoreModule,
		NgbModule.forRoot(),
		SharedModule,
		TranslateModule.forRoot({
			loader: {
				provide: TranslateLoader,
				useFactory: (http: HttpClient) => {
					return new TranslateHttpLoader(http);
				},
				deps: [HttpClient]
			}
		}),
		LocalizeRouterModule.forRoot(routes,{
			parser: {
				provide: LocalizeParser,
				useFactory: (translate, location, settings) =>
					new ManualParserLoader(translate, location, 
						new LocalizeRouterSettings(false, false, 'LocalStorage', 'LOCALIZE_DEFAULT_LANGUAGE', function(languages, cachedLang, browserLang) {
							return languages[0];
						}), config.languages, ''),
				deps: [TranslateService, Location, LocalizeRouterSettings]
			}
		})
	],
	providers: [
		CookieService,
		{ provide: ErrorHandler, useFactory: errorHandlerFactory },
	],
	bootstrap: [AppComponent],
	entryComponents: [
		CalendarModalComponent,
		TimeSlotModalComponent,
		DiscountModalComponent
	]
})

app.server.module.ts


import { Observable } from 'rxjs';
import { Location } from '@angular/common';
import { Routes } from '@angular/router';
import { LocalizeRouterSettings, LocalizeRouterModule, ManualParserLoader } from 'localize-router';
import { NgModule } from '@angular/core';
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
import { LazyUniversalModuleLoaderProvider } from 'localize-router-lazy-universal-module-loader';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { TranslateService, TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { routes, AppRoutingModule } from './app-routing.module';
import { config } from '@config/config';

let fs = require('fs');

export class TranslateUniversalLoader implements TranslateLoader {
	/**
	 * Gets the translations from the server
	 * @param lang
	 * @returns {any}
	 */
	public getTranslation(lang: string): Observable {
		return Observable.create(observer => {
			observer.next(JSON.parse(fs.readFileSync(`../src/assets/i18n/${lang}.json`, 'utf8')));
			observer.complete();
		});
	}
}

export function translateLoaderFactory() {
	return new TranslateUniversalLoader();
}

export class LocalizeUniversalLoader extends ManualParserLoader {
	/**
	 * Gets config from the server
	 * @param routes
	 */
	public load(routes: Routes): Promise {
		return new Promise((resolve: any) => {
			let data: any = JSON.parse(fs.readFileSync('../src/assets/locales.json', 'utf8'));
			this.locales = data.locales;
			this.prefix = '';
			this.init(routes).then(resolve);
		});
	}
}

export function localizeLoaderFactory(translate: TranslateService, location: Location, settings: LocalizeRouterSettings) {
	return new LocalizeUniversalLoader(translate, location, 
		new LocalizeRouterSettings(false, false, 'LocalStorage', 'LOCALIZE_DEFAULT_LANGUAGE', function(languages, cachedLang, browserLang) {
			return languages[0];
	}), config.languages, '');
}

@NgModule({
	imports: [
		AppModule,
		ServerModule,
		AppRoutingModule,
		ServerTransferStateModule,
		ModuleMapLoaderModule,
		TranslateModule.forRoot({
			loader: {
				provide: TranslateLoader,
				useFactory: translateLoaderFactory
			}
		}),
		LocalizeRouterModule.forRoot(routes,{
			parser: {
				provide: ManualParserLoader,
				useFactory: localizeLoaderFactory,
				deps: [TranslateService, Location, LocalizeRouterSettings]
			}
		})
	],
	providers: [
		LazyUniversalModuleLoaderProvider
	],
	bootstrap: [AppComponent],
})
export class AppServerModule { }

locales.json


{
    "locales": [
        "es",
        "en"
    ]
}

'config.languages' returns...


export const languages = [
	'es', 'en'
];

🌍 Your Environment

Angular Version:


Angular CLI: 7.3.8
Node: 11.13.0
OS: darwin x64
Angular: 7.2.14
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.13.8
@angular-devkit/build-angular     0.13.8
@angular-devkit/build-optimizer   0.13.8
@angular-devkit/build-webpack     0.13.8
@angular-devkit/core              7.3.8
@angular-devkit/schematics        7.3.8
@angular/cli                      7.3.8
@ngtools/webpack                  7.3.8
@schematics/angular               7.3.8
@schematics/update                0.13.8
rxjs                              6.5.1
typescript                        3.1.6
webpack                           4.29.0

Localize Router Version:


"localize-router": "^2.0.0-RC.2"

Anything else relevant?
I have tried to do changes in LocalizeRouterSettings, change ManualParserLoader by ** LocalizeParser**... But nothing.

I have asked to Melisandre, Geralt de Rivia and Gandalf... But nothing...

Who could be my Superman?

Thank you so much!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions