Beginning with version 18.2.3, @angular-architects/native-federation supports SSR and all the new hydration features modern Angular provides. It's a feature implemented for version 19 that was back-ported to 18. In this short article, I show how to use this possibility, which is vital for public portals and shops.
Example
As usual, the example contains a shell that loads a simple micro frontend. Both -- the micro frontend inside the shell -- is rendered on the server side:
Credits
Server-side Native Federation involves leveraging Import Maps on the server side. For this, the shown implementation uses a fork of Joel Denning's package node-loader/import-maps. Hence, all credits for this part go to Joel who constantly comes up with new ideas for improving the space of Micro Frontends.
Adding SSR and Native Federation to a Project
If @angular/ssr is added before Native Federation, the ng-add schematic provided by Native Federation will integrate both mechanisms with each other. The following commands assume an Angular workspace with a shell
and a mfe1
project:
# Add Micro Frontend
ng add @angular/ssr --project mfe1
ng add @angular-architects/native-federation --project mfe1 --type remote --port 4201
# Add Shell
ng add @angular/ssr --project shell
ng add @angular-architects/native-federation --project shell --type dynamic-host --port 4200
If Native Federation is already added, it can be temporarily removed to make sure the ng-add schematics provided by @angular/ssr work as expected:
# Remove Micro Frontend and Shell
ng g @angular-architects/native-federation:remove --project mfe1
ng g @angular-architects/native-federation:remove --project shell
# Add Micro Frontend
ng add @angular/ssr --project mfe1
ng add @angular-architects/native-federation --project mfe1 --type remote --port 4201
# Add Shell
ng add @angular/ssr --project shell
ng add @angular-architects/native-federation --project shell --type dynamic-host --port 4200
What Does the Schematic Generate?
Besides the usual tasks, Native Federation's ng-add
schematic updates the server.ts
in an SSR project:
import { initNodeFederation } from '@softarc/native-federation-node';
console.log('Starting SSR for Shell');
(async () => {
await initNodeFederation({
remotesOrManifestUrl: '../browser/federation.manifest.json',
relBundlePath: '../browser/',
});
await import('./bootstrap-server');
})();
This code initializes Federation on the server side. Then, it delegates to the file bootstrap-server.ts
, which starts the server with the same code usually found in server.ts.
Besides this, the default port used is updated to the one passed to --port
when ng add
was called. Also, it adds CORS support.
Limitation for ng serve
For technical reasons, ng serve
only loads the micro frontend into the shell on the client side. A production build created with ng build,
however, renders everything on the server side, too.
To prevent server-side errors when running ng serve, the code should provide a server-side fallback for the loaded Micro Frontend. For this, loadRemoteModule
now contains a fallback
property:
import { Routes } from '@angular/router';
import { loadRemoteModule } from '@angular-architects/native-federation';
import { DummyComponent } from './dummy/dummy.component';
import { HomeComponent } from './home/home.component';
export const routes: Routes = [
{
path: '',
pathMatch: 'full',
component: HomeComponent
},
{
path: 'mfe1',
loadComponent: () => loadRemoteModule({
remoteName: 'mfe1',
exposedModule: './Component',
fallback: DummyComponent
})
}
];
The fallback can, for instance, be a component with an empty template or a routing configuration with a catch-all route pointing to such a component.
We will try to remove this limitation. However, it should not be a massive show-stopper as SSR is first and foremost needed in production, and developers usually work mainly on their micro front end. Also, providing a fallback makes sense anyway.
Only SSR for Shell Needed
While one can totally activate SSR and hydration for both, the shell and the Micro Frontends, in many cases the latter one can be skipped -- especially if the users always load the Micro Frontends via the shell. Even if the Micro Frontend itself does not use SSR, the shell will render it on the server side. This simplifies the entire solution.
Conclusion
Beginning with version 18.2.3, @angular-architects/native-federation supports SSR. If the ng-add schematic detects an SSR project, it updates the server-side code automatically.
More on this: Angular Architecture Workshop (online, interactive, advanced)
Become an expert for enterprise-scale and maintainable Angular applications with our Angular Architecture workshop!