Angular MFE Remote Configuration | Advanced Setup
Once your host app and remotes are wired up with static remoteEntry.js URLs, the next problem shows up fast: those URLs are different in every environment, and hardcoding them means a rebuild for every deployment target. This guide covers configuring remotes dynamically instead.
π§ Dynamic Remote URLs
Section titled βπ§ Dynamic Remote URLsβInstead of baking remote URLs into webpack.config.js at build time, load them at runtime from environment-specific config:
// remote-manifest.json (deployed alongside the host, swapped per environment){ "userDashboard": "https://mfe-user-dashboard.azurestaticapps.net/remoteEntry.js", "transactionHistory": "https://mfe-transaction-history.azurestaticapps.net/remoteEntry.js"}// main.ts β fetch the manifest before bootstrappingimport { loadManifest } from '@angular-architects/module-federation';
loadManifest('/assets/remote-manifest.json') .then(() => import('./bootstrap')) .catch(err => console.error(err));The hostβs compiled bundle never needs to know the real URLs β only the manifest file (a plain JSON asset, swappable without a rebuild) does.
π Per-Environment Configuration
Section titled βπ Per-Environment Configurationβexport const environment = { production: false, remoteManifest: '/assets/remote-manifest.dev.json'};
// environment.prod.tsexport const environment = { production: true, remoteManifest: '/assets/remote-manifest.prod.json'};Each environmentβs manifest points at that environmentβs actual deployed remotes β dev host loads dev remotes, staging loads staging remotes, without touching application code.
π’ Versioning Remotes
Section titled βπ’ Versioning RemotesβTwo independent teams shipping to the same remote name is a recipe for a host suddenly loading an incompatible version. Options, in increasing order of safety:
- Version in the URL path:
https://mfe-user-dashboard.example.com/v2/remoteEntry.jsβ old hosts keep working against/v1/until theyβre explicitly updated. - Version in the manifest, not the remote: keep the remoteβs URL stable, but pin which manifest each host environment loads β rolling back is then a manifest swap, not a remote redeploy.
- Shared dependency version negotiation:
shareAll({ strictVersion: true })(already in yourwebpack.config.jsfrom the Module Federation setup) fails loudly at load time on an Angular/RxJS version mismatch, rather than producing a subtle runtime bug.
π‘οΈ Handling Load Failures
Section titled βπ‘οΈ Handling Load FailuresβA remote thatβs down shouldnβt take the whole host app down with it:
{ path: 'transactions', loadComponent: () => loadRemoteModule({ remoteEntry: environment.remotes.transactionHistory, remoteName: 'transactionHistory', exposedModule: './Component' }) .then(m => m.TransactionHistory) .catch(() => import('./fallback/remote-unavailable.component').then(m => m.RemoteUnavailableComponent))}Route-level .catch() on the loadComponent promise is the simplest guard β it swaps in a small βthis feature is temporarily unavailableβ component instead of an unhandled navigation error.
Next steps
Section titled βNext stepsβ- Apply this to the host you built in Host Application Setup
- See Advanced Concepts for shared state and cross-MFE communication patterns