I upgraded angular 12 up to angular 17 and now I’m experiencing the following warning pop-up in my console when serving my angular application locally via ng serve.
NG0505: Angular hydration was requested on the client, but there was no serialized information present in the server response, thus hydration was not enabled. Make sure the `provideClientHydration()` is included into the list of providers in the server part of the application configuration. Find more at https://angular.io/errors/NG0505
I am using NgModule and I am providing ‘provideClientHydration’ inside my app.module.ts file. As mentioned inside Angular’s documentation for Hydration https://v17.angular.io/guide/hydration.
I provide the following files related to server-side rending within my application.
server.ts
import 'zone.js/node';
import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import * as express from 'express';
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import AppServerModule from './src/main.server';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html'))
? join(distFolder, 'index.original.html')
: join(distFolder, 'index.html');
const commonEngine = new CommonEngine();
server.set('view engine', 'html');
server.set('views', distFolder);
// Server static files from /browser
server.get('*.*', (req, res, next) => {
next();
}, express.static(join(distFolder), { maxAge: '1y', fallthrough: false }));
// All regular routes use the Angular engine
server.get('*', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
bootstrap: AppServerModule,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: distFolder,
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
return server;
}
function run(): void {
const port = process.env['PORT'] || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
run();
export default AppServerModule;
main.server.ts
export { AppServerModule as default } from './app/app.module.server';
app.module.server.ts (here’s where the AppModule is imported which I understand ‘provideClientHydration’ gets included with the server)
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [
AppModule,
ServerModule,
],
bootstrap: [AppComponent],
})
export class AppServerModule {}
app.module.ts (simplified)
...
import { BrowserModule, provideClientHydration } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { APP_ID, NgModule } from '@angular/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';
import { SessionModule } from './session/session.module';
import { SharedModule } from './shared/shared.module';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
CoreModule,
FormsModule,
ReactiveFormsModule,
RouterModule.forRoot([
{ path: 'accessibility', data: { title: 'Accessibility'}, loadChildren: () => import('./accessibility/accessibility.module').then(m => m.AccessibilityModule) },
{ path: 'bag', data: { title: 'Bag' }, loadChildren: () => import('./shopping-bag/shopping-bag.module') .then(m => m.ShoppingBagModule) },
{ path: 'faq', data: { title: 'FAQ' }, loadChildren: () => import('./faq/faq.module') .then(m => m.FAQModule) },
{ path: '', data: { title: '' }, loadChildren: () => import('./landing/landing.module') .then(m => m.LandingModule) },
{ path: '**', data: { title: '' }, loadChildren: () => import('./error/error.module') .then(m => m.ErrorModule) }
], { anchorScrolling: 'enabled', scrollPositionRestoration: 'top' }),
SessionModule,
SharedModule,
NgbModule
],
providers: [
[{ provide: APP_ID, useValue: 'webapp' }],
provideClientHydration() // providing provideClientHydration here
],
bootstrap: [AppComponent]
})
export class AppModule { }
As far as I can tell I am providing ‘provideClientHydration’ to the server on bootstrap. I’m not sure what I may be missing or where to look to help debug this further. Any help would be much appreciated. Thank you.