66 * found in the LICENSE file at https://angular.dev/license
77 */
88
9- import { EnvironmentProviders , InjectionToken , makeEnvironmentProviders } from '@angular/core' ;
9+ import {
10+ EnvironmentProviders ,
11+ InjectionToken ,
12+ Provider ,
13+ Type ,
14+ makeEnvironmentProviders ,
15+ } from '@angular/core' ;
16+ import { type DefaultExport , ROUTES , type Route } from '@angular/router' ;
17+
18+ /**
19+ * The internal path used for the app shell route.
20+ * @internal
21+ */
22+ const APP_SHELL_ROUTE = 'ng-app-shell' ;
23+
24+ /**
25+ * Identifies a particular kind of `ServerRoutesFeatureKind`.
26+ * @see {@link ServerRoutesFeature }
27+ * @developerPreview
28+ */
29+ enum ServerRoutesFeatureKind {
30+ AppShell ,
31+ }
32+
33+ /**
34+ * Helper type to represent a server routes feature.
35+ * @see {@link ServerRoutesFeatureKind }
36+ * @developerPreview
37+ */
38+ interface ServerRoutesFeature < FeatureKind extends ServerRoutesFeatureKind > {
39+ ɵkind : FeatureKind ;
40+ ɵproviders : Provider [ ] ;
41+ }
1042
1143/**
1244 * Different rendering modes for server routes.
13- * @see {@link provideServerRoutesConfig }
45+ * @see {@link provideServerRouting }
1446 * @see {@link ServerRoute }
1547 * @developerPreview
1648 */
@@ -148,7 +180,7 @@ export interface ServerRouteServer extends ServerRouteCommon {
148180
149181/**
150182 * Server route configuration.
151- * @see {@link provideServerRoutesConfig }
183+ * @see {@link provideServerRouting }
152184 * @developerPreview
153185 */
154186export type ServerRoute =
@@ -163,17 +195,16 @@ export type ServerRoute =
163195 * This interface defines the optional settings available for configuring server routes
164196 * in the server-side environment, such as specifying a path to the app shell route.
165197 *
166- * @see {@link provideServerRoutesConfig }
167- * @developerPreview
198+ *
199+ * @see {@link provideServerRouting }
200+ * @deprecated use `provideServerRouting`. This will be removed in version 20.
168201 */
169202
170203export interface ServerRoutesConfigOptions {
171204 /**
172205 * Defines the route to be used as the app shell, which serves as the main entry
173206 * point for the application. This route is often used to enable server-side rendering
174207 * of the application shell for requests that do not match any specific server route.
175- *
176- * @see {@link https://angular.dev/ecosystem/service-workers/app-shell | App shell pattern on Angular.dev }
177208 */
178209 appShellRoute ?: string ;
179210}
@@ -182,7 +213,13 @@ export interface ServerRoutesConfigOptions {
182213 * Configuration value for server routes configuration.
183214 * @internal
184215 */
185- export interface ServerRoutesConfig extends ServerRoutesConfigOptions {
216+ export interface ServerRoutesConfig {
217+ /**
218+ * Defines the route to be used as the app shell.
219+ */
220+ appShellRoute ?: string ;
221+
222+ /** List of server routes for the application. */
186223 routes : ServerRoute [ ] ;
187224}
188225
@@ -204,6 +241,8 @@ export const SERVER_ROUTES_CONFIG = new InjectionToken<ServerRoutesConfig>('SERV
204241 *
205242 * @see {@link ServerRoute }
206243 * @see {@link ServerRoutesConfigOptions }
244+ * @see {@link provideServerRouting }
245+ * @deprecated use `provideServerRouting`. This will be removed in version 20.
207246 * @developerPreview
208247 */
209248export function provideServerRoutesConfig (
@@ -223,3 +262,83 @@ export function provideServerRoutesConfig(
223262 } ,
224263 ] ) ;
225264}
265+
266+ /**
267+ * Sets up the necessary providers for configuring server routes.
268+ * This function accepts an array of server routes and optional configuration
269+ * options, returning an `EnvironmentProviders` object that encapsulates
270+ * the server routes and configuration settings.
271+ *
272+ * @param routes - An array of server routes to be provided.
273+ * @param features - (Optional) server routes features.
274+ * @returns An `EnvironmentProviders` instance with the server routes configuration.
275+ *
276+ * @see {@link ServerRoute }
277+ * @see {@link withAppShell }
278+ * @developerPreview
279+ */
280+ export function provideServerRouting (
281+ routes : ServerRoute [ ] ,
282+ ...features : ServerRoutesFeature < ServerRoutesFeatureKind > [ ]
283+ ) : EnvironmentProviders {
284+ const config : ServerRoutesConfig = { routes } ;
285+ const hasAppShell = features . some ( ( f ) => f . ɵkind === ServerRoutesFeatureKind . AppShell ) ;
286+ if ( hasAppShell ) {
287+ config . appShellRoute = APP_SHELL_ROUTE ;
288+ }
289+
290+ const providers : Provider [ ] = [
291+ {
292+ provide : SERVER_ROUTES_CONFIG ,
293+ useValue : config ,
294+ } ,
295+ ] ;
296+
297+ for ( const feature of features ) {
298+ providers . push ( ...feature . ɵproviders ) ;
299+ }
300+
301+ return makeEnvironmentProviders ( providers ) ;
302+ }
303+
304+ /**
305+ * Configures the app shell route with the provided component.
306+ *
307+ * The app shell serves as the main entry point for the application and is commonly used
308+ * to enable server-side rendering (SSR) of the application shell. It handles requests
309+ * that do not match any specific server route, providing a fallback mechanism and improving
310+ * perceived performance during navigation.
311+ *
312+ * This configuration is particularly useful in applications leveraging Progressive Web App (PWA)
313+ * patterns, such as service workers, to deliver a seamless user experience.
314+ *
315+ * @param component The Angular component to render for the app shell route.
316+ * @returns A server routes feature configuration for the app shell.
317+ *
318+ * @see {@link provideServerRouting }
319+ * @see {@link https://angular.dev/ecosystem/service-workers/app-shell | App shell pattern on Angular.dev }
320+ */
321+ export function withAppShell (
322+ component : Type < unknown > | ( ( ) => Promise < Type < unknown > | DefaultExport < Type < unknown > > > ) ,
323+ ) : ServerRoutesFeature < ServerRoutesFeatureKind . AppShell > {
324+ const routeConfig : Route = {
325+ path : APP_SHELL_ROUTE ,
326+ } ;
327+
328+ if ( 'ɵcmp' in component ) {
329+ routeConfig . component = component as Type < unknown > ;
330+ } else {
331+ routeConfig . loadComponent = component as ( ) => Promise < Type < unknown > > ;
332+ }
333+
334+ return {
335+ ɵkind : ServerRoutesFeatureKind . AppShell ,
336+ ɵproviders : [
337+ {
338+ provide : ROUTES ,
339+ useValue : routeConfig ,
340+ multi : true ,
341+ } ,
342+ ] ,
343+ } ;
344+ }
0 commit comments