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
.
Latest comments (3)
It is now implemented in Angular v16 according to this (
github.com/angular/universal/pull/...)
ref: reddit.com/r/angular/comments/zqko...
Do we need to render each standalone component?
Would you mid sharing whole example?