I am new to Angular ssr, you can see code below
Issue
If I enter to client route directly, first it shows
Rendered by server
but quickly after that it rerenders page and shows:
Rendered by browser
I think I know why this happens, but to be sure can someone provide a good explanation? also, Can I somehow avoid this behavior and force browser to render html that comes from server? should I worry about this?
client.component.ts
@Component({
selector: "client",
template: "<p>Rendered by {{ renderer }}</p>",
styleUrls: ["./dumco.component.css"]
})
export class ClientComponent implements OnInit {
renderer: string;
bla: any = [];
constructor(private http: HttpClient, @Inject(PLATFORM_ID) platformId: any) {
this.renderer = isPlatformBrowser(platformId) ? "Browser" : "Server";
}
}
app-routing.module.ts
import { NgModule } from "@angular/core";
import { RouterModule, PreloadAllModules } from "@angular/router";
import { AppComponent } from "./app.component";
import { CompfComponent } from "./compf/compf.component"
import { HomeComponent } from "./home/home.component"
export const appRoutes = [
{
path: "",
component: HomeComponent
},
{
path: "comp",
component: CompfComponent
},
{
path: "client",
loadChildren: () => import("./client/client.module").then(m => m.ClientModule),
data: { title: "Static Data - Clients" }
},
];
// preloadingStrategy: PreloadAllModules,
@NgModule({
imports: [RouterModule.forRoot(appRoutes, { onSameUrlNavigation: "reload", initialNavigation: 'enabled' })],
exports: [RouterModule]
})
export class AppRoutingModule { }
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from "@angular/common/http";
import { AppRoutingModule } from "./app-routing.module"
import { AppComponent } from './app.component';
import { CompfComponent } from './compf/compf.component';
import { HomeComponent } from './home/home.component';
import { TransferHttpCacheModule } from "@nguniversal/common"
@NgModule({
declarations: [
AppComponent,
CompfComponent,
HomeComponent
],
imports: [
HttpClientModule,
TransferHttpCacheModule,
BrowserModule.withServerTransition({ appId: 'serverApp' }),
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
app.server.module.ts
import { NgModule } from '@angular/core';
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [
AppModule,
ServerModule,
ServerTransferStateModule
],
bootstrap: [AppComponent],
})
export class AppServerModule {}
This is normal behaviour for angular universal. Here is the normal flow:
You do not really have to worry about this. In a real situation, you'd have your components make API calls. To prevent the client side making the same calls that have already been made server side, you can use angular TransferState to serialise the API data in the HTML generated server side, so that the client side can use that data straight away instead of making API calls again.
That way, the HTML generated by the client should be the same as the one that came from the server. (Unless of course you specifically display different data server and client side, like in your example)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With