A reusable Angular host application that bootstraps Octa microfrontends with runtime branding, tenant configuration, and MFE orchestration. Branding, layout, and navigation are entirely data-driven via JSON so new clients can be onboarded without rebuilding the shell or MFEs.
- Runtime branding — load tenant-specific light/dark theme JSON, convert to CSS variables, and cascade into Shadow DOM for Angular Web Components.
- Configurable shell layout — header, sidebar, notifications, footer, and menus hydrate from
<tenant>.config.jsonat runtime. - MFE orchestration — declarative registry for Module Federation/Web Component endpoints, injected on demand with caching and developer overrides.
- Caching & resilience — theme JSON is cached in
localStoragewith versioning + TTL. Fallback themes/logos/icons apply if a fetch fails. - Developer-friendly — query
?tenant=expocityto hot-swap tenants,/style-guidepreview of tokens, and automatic fallback assets for local MFE dev.
npm install
npm startThe shell serves on http://localhost:4200. Append ?tenant=khidmah or ?tenant=expocity to switch runtime branding. Tenant preference and theme mode are persisted in localStorage.
src/
├── app/
│ ├── core/ # models + services (config, theme, MFE loader)
│ ├── layout/ # header, sidebar, footer, notifications, toggle
│ ├── shared/ # MFE host, style guide, not-found components
│ └── features/ # dashboard placeholder + future routes
├── assets/
│ ├── config/ # <tenant>.config.json
│ ├── themes/ # <tenant>_<mode>.json + fallbacks
│ ├── icons/ # tenant branded SVG icons
│ └── logos/ # tenant logos/marks
{
"meta": { "tenant": "khidmah", "mode": "light", "version": "1.0.0" },
"colors": { "primary": "#0F766E", "surface": "#FFFFFF" },
"typography": { "font-family-base": "'Inter', sans-serif" },
"spacing": { "md": "16px" },
"radius": { "pill": "999px" },
"layout": { "sidebar-width": "280px" },
"components": { "header": { "background": "#fff" } },
"icons": { "dashboard": { "type": "svg", "value": "assets/icons/khidmah/dashboard.svg" } },
"logos": { "main": { "type": "svg", "value": "assets/logos/khidmah-logo.svg" } }
}The ThemeService flattens every token into CSS variables (--octa-colors-primary, --octa-icons-dashboard, etc.) and applies them to :root, so any Web Component (even inside Shadow DOM) can call var(--octa-colors-primary).
Key fields:
layout— sidebar placement/width, footer copy, notification toggle.defaultTheme— URLs for light/dark/fallback JSON + cache version.menu— renders sidebar and maps tomfeIdroutes.mfeRegistry— metadata for each remote (tag name, remoteEntry, dev overrides).notifications— banner items shown above the layout.developer— fallback theme + dummy user shown in header.
assets/config/client.config.jsonis the default runtime contract. Update this file (or drop in additional<tenant>.config.jsonfiles) to change the shell branding, menu, or MFE registry without rebuilding.ShellConfigServicefetches the JSON duringAPP_INITIALIZER, blocks bootstrap until the payload is ready, and exposes the structure throughconfigSignal/config$so any component can react to changes.- The shell automatically renders
config.appNameand the primary logo sourced fromconfig.branding.logoUrl(or the theme logos if provided). - To switch clients at runtime, either replace the
client.config.jsonasset on the server or duplicate it as<tenant>.config.jsonand load it via?tenant=<tenant>(or callShellConfigService.switchTenant('<tenant>')). The updated JSON applies on the next refresh—no rebuild required. - Keep config versioned (
configVersion) so ops teams know which payload is live, and aligndefaultTheme.cacheVersionwith your theme bundle to leverage caching.
- Register the Web Component in
<tenant>.config.json(tagName, optionalremoteEntry). - Use
/mfe/<id>route to mount it. The shell injects scripts once and provides tenant + theme context through CSS variables anddata-tenantattributes. - For local dev, point
localDev.remoteEntryto yourng serveoutput; toggle via query params without rebuilding the shell.
| Command | Description |
|---|---|
npm start |
Serve the shell with live reload |
npm run build |
Production build |
npm run test |
Execute unit tests (Vitest) |
- Wire ThemeService to remote CDN once endpoints are available.
- Expand Module Federation handling (lazy routes, manifests) as MFEs evolve.
- Hook notifications/user profile to real APIs.