I have a little problem with Angular 5.2.10 TransferState
module. Currently I'm using Angular Universal (latest version) to make my site SEO friendly. Everything is working fine except one thing... Page is loading first - on server side, then content disappear and load on browser side (screen).
I've created service for TransferState
implementation (you can see it below).
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import "rxjs/add/operator/map";
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/share';
import { Observable } from 'rxjs/Observable';
import { TransferState, makeStateKey, DomSanitizer, SafeHtml } from '@angular/platform-browser';
interface pageData {
banner: string;
data: any;
html: SafeHtml;
text: string;
title: string;
}
@Injectable()
export class ServerService {
constructor(private http: HttpClient, private state: TransferState, private sanitizer: DomSanitizer) { }
getResponse(url): Observable<any> {
url = makeStateKey<Promise<any>>(url);
let temp = this.state.hasKey(url);
if (!temp)
return this.http.get<any>(url).map(
(response: any) => {
let data = response;
this.state.set(url, data);
return data;
}
).share();
else {
return Observable.of(this.state.get(url, null as Observable<any>));
}
}
async getResponseAsync(url): Promise<any> {
let temp = await this.state.hasKey(url);
url = makeStateKey<Promise<any>>(url);
if (!await temp)
return this.http.get<any>(url).toPromise().then(
async (response: any) => {
await this.state.set(url, await response);
return await response;
}
);
else {
return await this.state.get(url, null as Promise<any>)
}
}
}
I've also tried solution with TransferHttpCacheModule
, but problem remains.
main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch(err => console.log(err));
});
app.server.module.ts
import { NgModule } from '@angular/core';
import { ServerModule, ServerTransferStateModule } from "@angular/platform-server";
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
imports: [
AppModule,
ServerModule,
ServerTransferStateModule,
ModuleMapLoaderModule,
NoopAnimationsModule,
],
providers: [],
bootstrap: [ AppComponent ],
})
export class AppServerModule {}
app.module.ts
// Core
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';
import { ServiceWorkerModule } from '@angular/service-worker';
import { FormsModule, ReactiveFormsModule, NgForm } from '@angular/forms';
import { NgForageModule, NgForageConfig, NgForageOptions } from "ngforage";
import { NgProgressModule } from '@ngx-progressbar/core';
// Config
import { Config } from './config';
// Compontents
import { AppComponent } from './app.component';
import { ContainerComponent } from './components/container/container.component'
import { ContainerModule } from './components/container/container.module'
// Environment
import { environment } from '../environments/environment';
import { NotfoundComponent } from './components/notfound/notfound.component';
import { NotfoundModule } from './components/notfound/notfound.module';
const routes: Routes = [
{
path: '',
pathMatch: 'full',
redirectTo: '/pl'
},
{
path: 'pl/home',
redirectTo: 'pl'
},
{
path: '404',
component: NotfoundComponent
},
{
path: ':lang',
component: ContainerComponent
},
{
path: ':lang/:index',
component: ContainerComponent,
},
{
path: '**',
redirectTo: '404'
}
];
@NgModule({
declarations: [
AppComponent,
],
imports: [
RouterModule.forRoot(routes, { initialNavigation: 'enabled', preloadingStrategy: PreloadAllModules }),
BrowserModule.withServerTransition({ appId: 'main-app' }),
BrowserTransferStateModule,
ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production }),
BrowserAnimationsModule,
NgProgressModule.forRoot(),
NgForageModule.forRoot(),
ContainerModule,
NotfoundModule,
],
providers: [
Config
],
bootstrap: [AppComponent]
})
export class AppModule{
constructor(ngfConfig: NgForageConfig) {
ngfConfig.configure({
name: 'apiDB',
driver: [ // defaults to indexedDB -> webSQL -> localStorage -> sessionStorage
NgForageConfig.DRIVER_INDEXEDDB,
NgForageConfig.DRIVER_LOCALSTORAGE
]
});
}
}
Example repo you can see there (some components are out of date - most important modules you have above)
Do you know how to fix that issue ? Or it's core bug, and I have to wait for fixes ?
Page blink, after inserting state node in document tree (this one marked below main-app-state )
Edit It's not Service Worker issue also, I've tried to turn it off and still the same.
Github issue here