With the arrival of Standalone Component with Angular 15, it is now possible to do without @NgModules entirely. This opens the door to new possibilities.
It is now possible to bootstrap an Angular application by providing an entry point component with a list of providers in the main.ts :
bootstrapApplication(AppComponent, {
providers: [
provideAnimations(),
provideRouter(routes)
]
})
However, with this new approach, it is not yet possible to simply take advantage of the server side rendering (SSR) with Angular Universal because the function ngExpressEngine only takes a module parameter and not a component:
import express from 'express';
import { ngExpressEngine } from '@nguniversal/express-engine';
const app = express();
// Set the engine
app.engine(
'html',
// Bootstrap and render NgModule with express adapter for `@angular/platform-server`
ngExpressEngine({
// Take a module but we would like to provide component
bootstrap: ServerAppModule
}),
);
app.set('view engine', 'html');
app.get('/**/*', (req: Request, res: Response) => {
res.render('../dist/index', {
req,
res,
});
});
On the other hand it is possible to use manually the render function provided by @angular/platform-server.
This forces us to redo the work done by Angular Universal inside ngExpressEngine but it's the only possibility while waiting for the support of standalone component :
import express from 'express';
import type { Request, Response } from 'express';
import * as fs from 'fs';
import { renderApplication } from '@angular/platform-server'
const app = express();
app.engine('html', async (path, options, callback) => {
const document = fs.readFileSync(path, 'utf-8')
const { req } = { ...options } as {req: Request, res: Response};
// Bootstrap and render a Standalone Component
const html = await renderApplication(AppComponent, {
appId: 'server-app',
document: document,
url: `${req.baseUrl}${req.url}`,
providers: [
provideRouter(routes),
]
});
callback(null, html)
});
app.set('view engine', 'html');
app.get('/**/*', (req: Request, res: Response) => {
res.render('../dist/index', {
req,
res,
});
});
Thanks to the function renderApplication, it is possible to bootstrap an Angular component and render it on the server side while waiting for the full support of Standalone Component in Angular Universal with the provided function ngExpressEngine.
Top comments (3)
It is now implemented in Angular v16 according to this (
github.com/angular/universal/pull/...)
ref: reddit.com/r/angular/comments/zqko...
Would you mid sharing whole example?
Do we need to render each standalone component?