From 233d27c547da65ce3ea8cc18c560ec5c989d51dd Mon Sep 17 00:00:00 2001 From: arturovt Date: Thu, 26 Feb 2026 01:14:06 +0200 Subject: [PATCH] feat: support function as options.template Allow `template` to accept a function `(props: AppProps) => string` in addition to a plain string. This enables dynamic template generation based on single-spa props at mount time. - Update `BaseSingleSpaAngularOptions` type to accept `string | ((props: AppProps) => string)` - Call the function with `props` in `getContainerElementAndSetTemplate` if `template` is a function - Update validation error message in `singleSpaAngular` to reflect both accepted types - Update navbar example app to use the new function form --- apps/navbar/src/main.single-spa.ts | 2 +- libs/single-spa-community-angular/internals/src/dom.ts | 6 +++++- libs/single-spa-community-angular/internals/src/types.ts | 2 +- libs/single-spa-community-angular/src/single-spa-angular.ts | 4 ++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/navbar/src/main.single-spa.ts b/apps/navbar/src/main.single-spa.ts index 9d3917aa..1ebd4ee5 100644 --- a/apps/navbar/src/main.single-spa.ts +++ b/apps/navbar/src/main.single-spa.ts @@ -10,7 +10,7 @@ const lifecycles = singleSpaAngular({ const platformRef = platformBrowser(provideSingleSpaPlatform()); return bootstrapApplication(AppComponent, appConfig, { platformRef }); }, - template: '', + template: () => '', NgZone: 'noop', Router, NavigationStart, diff --git a/libs/single-spa-community-angular/internals/src/dom.ts b/libs/single-spa-community-angular/internals/src/dom.ts index b05ad9b5..1e680f60 100644 --- a/libs/single-spa-community-angular/internals/src/dom.ts +++ b/libs/single-spa-community-angular/internals/src/dom.ts @@ -14,8 +14,12 @@ export function getContainerElementAndSetTemplate HTMLElement; export interface BaseSingleSpaAngularOptions { - template: string; + template: string | ((props: AppProps) => string); domElementGetter?: DomElementGetter; bootstrapFunction(props: AppProps): Promise | ApplicationRef>; } diff --git a/libs/single-spa-community-angular/src/single-spa-angular.ts b/libs/single-spa-community-angular/src/single-spa-angular.ts index 9d74eb9a..72f76a4b 100644 --- a/libs/single-spa-community-angular/src/single-spa-angular.ts +++ b/libs/single-spa-community-angular/src/single-spa-angular.ts @@ -31,8 +31,8 @@ export function singleSpaAngular(userOptions: SingleSpaAngularOptions): Li throw Error('single-spa-angular must be passed an options.bootstrapFunction'); } - if (typeof options.template !== 'string') { - throw Error('single-spa-angular must be passed options.template string'); + if (typeof options.template !== 'string' && typeof options.template !== 'function') { + throw Error('single-spa-angular must be passed options.template string or function'); } if (!options.NgZone) {