I followed the docs:
https://github.com/angular/universal/tree/master/modules/express-engine
Note, you bootstrap the app twice in server.ts, we need to provide the response every request.
Also we optionally inject the response into our app components, as the response will be NULL if the platform is the browser.
server.ts
some imports:
import {Response} from 'express';
import {RESPONSE} from '@nguniversal/express-engine/tokens';
engine:
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main');
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP),
]
}));
request handler:
app.get('*', async (req, res) => {
res.render('index.html', {req, res, providers: [
{
provide: RESPONSE,
useValue: res,
},
]}, (error, html) => {
if (error) {
console.log(`Error generating html for req ${req.url}`, error);
return (req as any).next(error);
}
res.send(html);
if (!error) {
if (res.statusCode === 200) {
//toCache(req.url, html);
}
}
});
});
routing:
const routes: Routes = [
{path: '404', component: NotFoundComponent},
...
{path: '**', redirectTo: '/404'}
];
component:
import { RESPONSE } from '@nguniversal/express-engine/tokens'
import { Component, OnInit, Inject, Optional } from '@angular/core'
import { Response } from 'express'
@Component({
selector: 'app-not-found',
templateUrl: './not-found.component.html',
styleUrls: ['./not-found.component.scss']
})
export class NotFoundComponent implements OnInit {
private response: Response;
constructor(@Optional() @Inject(RESPONSE) response: any) {
this.response = response;
}
ngOnInit() {
console.log('here with response', this.response);
if (this.response) {
// response will only be if we have express
// this.response.statusCode = 404;
this.response.status(404);
}
}
}