|
6 | 6 | * found in the LICENSE file at https://angular.io/license |
7 | 7 | */ |
8 | 8 |
|
9 | | -import {ApplicationRef, EnvironmentProviders, importProvidersFrom, InjectionToken, NgModuleRef, PlatformRef, Provider, Renderer2, StaticProvider, Type, ɵinternalCreateApplication as internalCreateApplication, ɵisPromise} from '@angular/core'; |
| 9 | +import {ApplicationRef, EnvironmentProviders, importProvidersFrom, InjectionToken, NgModuleRef, PlatformRef, Provider, Renderer2, StaticProvider, Type, ɵgetComponentDef as getComponentDef, ɵinternalCreateApplication as internalCreateApplication, ɵisPromise} from '@angular/core'; |
10 | 10 | import {BrowserModule, ɵTRANSITION_ID} from '@angular/platform-browser'; |
11 | 11 | import {first} from 'rxjs/operators'; |
12 | 12 |
|
@@ -153,11 +153,37 @@ export function renderModule<T>(moduleType: Type<T>, options: { |
153 | 153 | return _render(platform, platform.bootstrapModule(moduleType)); |
154 | 154 | } |
155 | 155 |
|
| 156 | +/** |
| 157 | + * Bootstraps an instance of an Angular application and renders it to a string. |
| 158 | +
|
| 159 | + * ```typescript |
| 160 | + * const bootstrap = () => bootstrapApplication(RootComponent, appConfig); |
| 161 | + * const output: string = await renderApplication(bootstrap); |
| 162 | + * ``` |
| 163 | + * |
| 164 | + * @param bootstrap A method that when invoked returns a promise that returns an `ApplicationRef` |
| 165 | + * instance once resolved. |
| 166 | + * @param options Additional configuration for the render operation: |
| 167 | + * - `document` - the document of the page to render, either as an HTML string or |
| 168 | + * as a reference to the `document` instance. |
| 169 | + * - `url` - the URL for the current render request. |
| 170 | + * - `platformProviders` - the platform level providers for the current render request. |
| 171 | + * |
| 172 | + * @returns A Promise, that returns serialized (to a string) rendered page, once resolved. |
| 173 | + * |
| 174 | + * @publicApi |
| 175 | + * @developerPreview |
| 176 | + */ |
| 177 | +export function renderApplication<T>(bootstrap: () => Promise<ApplicationRef>, options: { |
| 178 | + document?: string|Document, |
| 179 | + url?: string, |
| 180 | + platformProviders?: Provider[], |
| 181 | +}): Promise<string>; |
156 | 182 | /** |
157 | 183 | * Bootstraps an instance of an Angular application and renders it to a string. |
158 | 184 | * |
159 | | - * Note: the root component passed into this function *must* be a standalone one (should have the |
160 | | - * `standalone: true` flag in the `@Component` decorator config). |
| 185 | + * Note: the root component passed into this function *must* be a standalone one (should have |
| 186 | + * the `standalone: true` flag in the `@Component` decorator config). |
161 | 187 | * |
162 | 188 | * ```typescript |
163 | 189 | * @Component({ |
@@ -186,18 +212,40 @@ export function renderModule<T>(moduleType: Type<T>, options: { |
186 | 212 | * @developerPreview |
187 | 213 | */ |
188 | 214 | export function renderApplication<T>(rootComponent: Type<T>, options: { |
| 215 | + /** @deprecated use `APP_ID` token to set the application ID. */ |
189 | 216 | appId: string, |
190 | 217 | document?: string|Document, |
191 | 218 | url?: string, |
192 | 219 | providers?: Array<Provider|EnvironmentProviders>, |
193 | 220 | platformProviders?: Provider[], |
194 | | -}): Promise<string> { |
195 | | - const {document, url, platformProviders, appId} = options; |
| 221 | +}): Promise<string>; |
| 222 | +export function renderApplication<T>( |
| 223 | + rootComponentOrBootstrapFn: Type<T>|(() => Promise<ApplicationRef>), options: { |
| 224 | + appId?: string, |
| 225 | + document?: string|Document, |
| 226 | + url?: string, |
| 227 | + providers?: Array<Provider|EnvironmentProviders>, |
| 228 | + platformProviders?: Provider[], |
| 229 | + }): Promise<string> { |
| 230 | + const {document, url, platformProviders, appId = ''} = options; |
196 | 231 | const platform = _getPlatform(platformDynamicServer, {document, url, platformProviders}); |
| 232 | + |
| 233 | + if (isBootstrapFn(rootComponentOrBootstrapFn)) { |
| 234 | + return _render(platform, rootComponentOrBootstrapFn()); |
| 235 | + } |
| 236 | + |
197 | 237 | const appProviders = [ |
198 | 238 | importProvidersFrom(BrowserModule.withServerTransition({appId})), |
199 | 239 | importProvidersFrom(ServerModule), |
200 | 240 | ...(options.providers ?? []), |
201 | 241 | ]; |
202 | | - return _render(platform, internalCreateApplication({rootComponent, appProviders})); |
| 242 | + |
| 243 | + return _render( |
| 244 | + platform, |
| 245 | + internalCreateApplication({rootComponent: rootComponentOrBootstrapFn, appProviders})); |
| 246 | +} |
| 247 | + |
| 248 | +function isBootstrapFn(value: unknown): value is() => Promise<ApplicationRef> { |
| 249 | + // We can differentiate between a component and a bootstrap function by reading `cmp`: |
| 250 | + return typeof value === 'function' && !getComponentDef(value); |
203 | 251 | } |
0 commit comments