@angular/ssr 21.2.0-next.2 → 21.2.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular/ssr",
3
- "version": "21.2.0-next.2",
3
+ "version": "21.2.0-rc.1",
4
4
  "description": "Angular server side rendering utilities",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -29,12 +29,12 @@
29
29
  },
30
30
  "devDependencies": {
31
31
  "@angular-devkit/schematics": "workspace:*",
32
- "@angular/common": "21.2.0-next.3",
33
- "@angular/compiler": "21.2.0-next.3",
34
- "@angular/core": "21.2.0-next.3",
35
- "@angular/platform-browser": "21.2.0-next.3",
36
- "@angular/platform-server": "21.2.0-next.3",
37
- "@angular/router": "21.2.0-next.3",
32
+ "@angular/common": "21.2.0-rc.0",
33
+ "@angular/compiler": "21.2.0-rc.0",
34
+ "@angular/core": "21.2.0-rc.0",
35
+ "@angular/platform-browser": "21.2.0-rc.0",
36
+ "@angular/platform-server": "21.2.0-rc.0",
37
+ "@angular/router": "21.2.0-rc.0",
38
38
  "@schematics/angular": "workspace:*",
39
39
  "beasties": "0.4.1"
40
40
  },
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Defines a handler function type for transforming HTML content.
3
+ * This function receives an object with the HTML to be processed.
4
+ *
5
+ * @param ctx - An object containing the URL and HTML content to be transformed.
6
+ * @returns The transformed HTML as a string or a promise that resolves to the transformed HTML.
7
+ */
8
+ type HtmlTransformHandler = (ctx: {
9
+ url: URL;
10
+ html: string;
11
+ }) => string | Promise<string>;
12
+ /**
13
+ * Defines the names of available hooks for registering and triggering custom logic within the application.
14
+ */
15
+ type HookName = keyof HooksMapping;
16
+ /**
17
+ * Mapping of hook names to their corresponding handler types.
18
+ */
19
+ interface HooksMapping {
20
+ 'html:transform:pre': HtmlTransformHandler;
21
+ }
22
+ /**
23
+ * Manages a collection of hooks and provides methods to register and execute them.
24
+ * Hooks are functions that can be invoked with specific arguments to allow modifications or enhancements.
25
+ */
26
+ declare class Hooks {
27
+ /**
28
+ * A map of hook names to arrays of hook functions.
29
+ * Each hook name can have multiple associated functions, which are executed in sequence.
30
+ */
31
+ private readonly store;
32
+ /**
33
+ * Registers a new hook function under the specified hook name.
34
+ * This function should be a function that takes an argument of type `T` and returns a `string` or `Promise<string>`.
35
+ *
36
+ * @template Hook - The type of the hook name. It should be one of the keys of `HooksMapping`.
37
+ * @param name - The name of the hook under which the function will be registered.
38
+ * @param handler - A function to be executed when the hook is triggered. The handler will be called with an argument
39
+ * that may be modified by the hook functions.
40
+ *
41
+ * @remarks
42
+ * - If there are existing handlers registered under the given hook name, the new handler will be added to the list.
43
+ * - If no handlers are registered under the given hook name, a new list will be created with the handler as its first element.
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * hooks.on('html:transform:pre', async (ctx) => {
48
+ * return ctx.html.replace(/foo/g, 'bar');
49
+ * });
50
+ * ```
51
+ */
52
+ on<Hook extends HookName>(name: Hook, handler: HooksMapping[Hook]): void;
53
+ /**
54
+ * Checks if there are any hooks registered under the specified name.
55
+ *
56
+ * @param name - The name of the hook to check.
57
+ * @returns `true` if there are hooks registered under the specified name, otherwise `false`.
58
+ */
59
+ has(name: HookName): boolean;
60
+ }
61
+
62
+ /**
63
+ * Options for the Angular server application engine.
64
+ */
65
+ interface AngularAppEngineOptions {
66
+ /**
67
+ * A set of allowed hostnames for the server application.
68
+ */
69
+ allowedHosts?: readonly string[];
70
+ }
71
+ /**
72
+ * Angular server application engine.
73
+ * Manages Angular server applications (including localized ones), handles rendering requests,
74
+ * and optionally transforms index HTML before rendering.
75
+ *
76
+ * @remarks This class should be instantiated once and used as a singleton across the server-side
77
+ * application to ensure consistent handling of rendering requests and resource management.
78
+ */
79
+ declare class AngularAppEngine {
80
+ /**
81
+ * A flag to enable or disable the rendering of prerendered routes.
82
+ *
83
+ * Typically used during development to avoid prerendering all routes ahead of time,
84
+ * allowing them to be rendered on the fly as requested.
85
+ *
86
+ * @private
87
+ */
88
+ static ɵallowStaticRouteRender: boolean;
89
+ /**
90
+ * Hooks for extending or modifying the behavior of the server application.
91
+ * These hooks are used by the Angular CLI when running the development server and
92
+ * provide extensibility points for the application lifecycle.
93
+ *
94
+ * @private
95
+ */
96
+ static ɵhooks: Hooks;
97
+ /**
98
+ * The manifest for the server application.
99
+ */
100
+ private readonly manifest;
101
+ /**
102
+ * A set of allowed hostnames for the server application.
103
+ */
104
+ private readonly allowedHosts;
105
+ /**
106
+ * A map of supported locales from the server application's manifest.
107
+ */
108
+ private readonly supportedLocales;
109
+ /**
110
+ * A cache that holds entry points, keyed by their potential locale string.
111
+ */
112
+ private readonly entryPointsCache;
113
+ /**
114
+ * Creates a new instance of the Angular server application engine.
115
+ * @param options Options for the Angular server application engine.
116
+ */
117
+ constructor(options?: AngularAppEngineOptions);
118
+ /**
119
+ * Handles an incoming HTTP request by serving prerendered content, performing server-side rendering,
120
+ * or delivering a static file for client-side rendered routes based on the `RenderMode` setting.
121
+ *
122
+ * @param request - The HTTP request to handle.
123
+ * @param requestContext - Optional context for rendering, such as metadata associated with the request.
124
+ * @returns A promise that resolves to the resulting HTTP response object, or `null` if no matching Angular route is found.
125
+ *
126
+ * @remarks A request to `https://www.example.com/page/index.html` will serve or render the Angular route
127
+ * corresponding to `https://www.example.com/page`.
128
+ *
129
+ * @remarks
130
+ * To prevent potential Server-Side Request Forgery (SSRF), this function verifies the hostname
131
+ * of the `request.url` against a list of authorized hosts.
132
+ * If the hostname is not recognized and `allowedHosts` is not empty, a Client-Side Rendered (CSR) version of the
133
+ * page is returned otherwise a 400 Bad Request is returned.
134
+ * Resolution:
135
+ * Authorize your hostname by configuring `allowedHosts` in `angular.json` in:
136
+ * `projects.[project-name].architect.build.options.security.allowedHosts`.
137
+ * Alternatively, you pass it directly through the configuration options of `AngularAppEngine`.
138
+ *
139
+ * For more information see: https://angular.dev/best-practices/security#preventing-server-side-request-forgery-ssrf
140
+ */
141
+ handle(request: Request, requestContext?: unknown): Promise<Response | null>;
142
+ /**
143
+ * Handles requests for the base path when i18n is enabled.
144
+ * Redirects the user to a locale-specific path based on the `Accept-Language` header.
145
+ *
146
+ * @param request The incoming request.
147
+ * @returns A `Response` object with a 302 redirect, or `null` if i18n is not enabled
148
+ * or the request is not for the base path.
149
+ */
150
+ private redirectBasedOnAcceptLanguage;
151
+ /**
152
+ * Retrieves the Angular server application instance for a given request.
153
+ *
154
+ * This method checks if the request URL corresponds to an Angular application entry point.
155
+ * If so, it initializes or retrieves an instance of the Angular server application for that entry point.
156
+ * Requests that resemble file requests (except for `/index.html`) are skipped.
157
+ *
158
+ * @param request - The incoming HTTP request object.
159
+ * @returns A promise that resolves to an `AngularServerApp` instance if a valid entry point is found,
160
+ * or `null` if no entry point matches the request URL.
161
+ */
162
+ private getAngularServerAppForRequest;
163
+ /**
164
+ * Retrieves the exports for a specific entry point, caching the result.
165
+ *
166
+ * @param potentialLocale - The locale string used to find the corresponding entry point.
167
+ * @returns A promise that resolves to the entry point exports or `undefined` if not found.
168
+ */
169
+ private getEntryPointExports;
170
+ /**
171
+ * Retrieves the entry point for a given URL by determining the locale and mapping it to
172
+ * the appropriate application bundle.
173
+ *
174
+ * This method determines the appropriate entry point and locale for rendering the application by examining the URL.
175
+ * If there is only one entry point available, it is returned regardless of the URL.
176
+ * Otherwise, the method extracts a potential locale identifier from the URL and looks up the corresponding entry point.
177
+ *
178
+ * @param url - The URL of the request.
179
+ * @returns A promise that resolves to the entry point exports or `undefined` if not found.
180
+ */
181
+ private getEntryPointExportsForUrl;
182
+ /**
183
+ * Handles validation errors by logging the error and returning an appropriate response.
184
+ *
185
+ * @param error - The validation error to handle.
186
+ * @param request - The HTTP request that caused the validation error.
187
+ * @returns A promise that resolves to a `Response` object with a 400 status code if allowed hosts are configured,
188
+ * or `null` if allowed hosts are not configured (in which case the request is served client-side).
189
+ */
190
+ private handleValidationError;
191
+ }
192
+
193
+ export { AngularAppEngine, Hooks };
194
+ export type { AngularAppEngineOptions };
package/types/node.d.ts CHANGED
@@ -2,6 +2,7 @@ import { Type, ApplicationRef, StaticProvider } from '@angular/core';
2
2
  import { BootstrapContext } from '@angular/platform-browser';
3
3
  import { IncomingMessage, ServerResponse } from 'node:http';
4
4
  import { Http2ServerRequest, Http2ServerResponse } from 'node:http2';
5
+ import { AngularAppEngineOptions } from './_app-engine-chunk.js';
5
6
 
6
7
  interface CommonEngineOptions {
7
8
  /** A method that when invoked returns a promise that returns an `ApplicationRef` instance once resolved or an NgModule. */
@@ -10,6 +11,8 @@ interface CommonEngineOptions {
10
11
  providers?: StaticProvider[];
11
12
  /** Enable request performance profiling data collection and printing the results in the server console. */
12
13
  enablePerformanceProfiler?: boolean;
14
+ /** A set of hostnames that are allowed to access the server. */
15
+ allowedHosts?: readonly string[];
13
16
  }
14
17
  interface CommonEngineRenderOptions {
15
18
  /** A method that when invoked returns a promise that returns an `ApplicationRef` instance once resolved or an NgModule. */
@@ -38,6 +41,7 @@ declare class CommonEngine {
38
41
  private readonly templateCache;
39
42
  private readonly inlineCriticalCssProcessor;
40
43
  private readonly pageIsSSG;
44
+ private readonly allowedHosts;
41
45
  constructor(options?: CommonEngineOptions | undefined);
42
46
  /**
43
47
  * Render an HTML document for a specific URL with specified
@@ -51,6 +55,11 @@ declare class CommonEngine {
51
55
  private getDocument;
52
56
  }
53
57
 
58
+ /**
59
+ * Options for the Angular Node.js server application engine.
60
+ */
61
+ interface AngularNodeAppEngineOptions extends AngularAppEngineOptions {
62
+ }
54
63
  /**
55
64
  * Angular server application engine.
56
65
  * Manages Angular server applications (including localized ones), handles rendering requests,
@@ -61,22 +70,40 @@ declare class CommonEngine {
61
70
  */
62
71
  declare class AngularNodeAppEngine {
63
72
  private readonly angularAppEngine;
64
- constructor();
73
+ /**
74
+ * Creates a new instance of the Angular Node.js server application engine.
75
+ * @param options Options for the Angular Node.js server application engine.
76
+ */
77
+ constructor(options?: AngularNodeAppEngineOptions);
65
78
  /**
66
79
  * Handles an incoming HTTP request by serving prerendered content, performing server-side rendering,
67
80
  * or delivering a static file for client-side rendered routes based on the `RenderMode` setting.
68
81
  *
69
- * This method adapts Node.js's `IncomingMessage` or `Http2ServerRequest`
82
+ * This method adapts Node.js's `IncomingMessage`, `Http2ServerRequest` or `Request`
70
83
  * to a format compatible with the `AngularAppEngine` and delegates the handling logic to it.
71
84
  *
72
- * @param request - The incoming HTTP request (`IncomingMessage` or `Http2ServerRequest`).
85
+ * @param request - The incoming HTTP request (`IncomingMessage`, `Http2ServerRequest` or `Request`).
73
86
  * @param requestContext - Optional context for rendering, such as metadata associated with the request.
74
87
  * @returns A promise that resolves to the resulting HTTP response object, or `null` if no matching Angular route is found.
75
88
  *
76
89
  * @remarks A request to `https://www.example.com/page/index.html` will serve or render the Angular route
77
90
  * corresponding to `https://www.example.com/page`.
91
+ *
92
+ * @remarks
93
+ * To prevent potential Server-Side Request Forgery (SSRF), this function verifies the hostname
94
+ * of the `request.url` against a list of authorized hosts.
95
+ * If the hostname is not recognized and `allowedHosts` is not empty, a Client-Side Rendered (CSR) version of the
96
+ * page is returned otherwise a 400 Bad Request is returned.
97
+ *
98
+ * Resolution:
99
+ * Authorize your hostname by configuring `allowedHosts` in `angular.json` in:
100
+ * `projects.[project-name].architect.build.options.security.allowedHosts`.
101
+ * Alternatively, you can define the allowed hostname via the environment variable `process.env['NG_ALLOWED_HOSTS']`
102
+ * or pass it directly through the configuration options of `AngularNodeAppEngine`.
103
+ *
104
+ * For more information see: https://angular.dev/best-practices/security#preventing-server-side-request-forgery-ssrf
78
105
  */
79
- handle(request: IncomingMessage | Http2ServerRequest, requestContext?: unknown): Promise<Response | null>;
106
+ handle(request: IncomingMessage | Http2ServerRequest | Request, requestContext?: unknown): Promise<Response | null>;
80
107
  }
81
108
 
82
109
  /**
@@ -176,4 +203,4 @@ declare function createWebRequestFromNodeRequest(nodeRequest: IncomingMessage |
176
203
  declare function isMainModule(url: string): boolean;
177
204
 
178
205
  export { AngularNodeAppEngine, CommonEngine, createNodeRequestHandler, createWebRequestFromNodeRequest, isMainModule, writeResponseToNodeResponse };
179
- export type { CommonEngineOptions, CommonEngineRenderOptions, NodeRequestHandlerFunction };
206
+ export type { AngularNodeAppEngineOptions, CommonEngineOptions, CommonEngineRenderOptions, NodeRequestHandlerFunction };
package/types/ssr.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { Type, EnvironmentProviders, Provider, ApplicationRef } from '@angular/core';
2
2
  import { DefaultExport } from '@angular/router';
3
3
  import { BootstrapContext } from '@angular/platform-browser';
4
+ import { Hooks } from './_app-engine-chunk.js';
5
+ export { AngularAppEngine, AngularAppEngineOptions } from './_app-engine-chunk.js';
4
6
  import Beasties from '../third_party/beasties';
5
7
 
6
8
  /**
@@ -498,6 +500,10 @@ interface AngularAppEngineManifest {
498
500
  * - `value`: The url segment associated with that locale.
499
501
  */
500
502
  readonly supportedLocales: Readonly<Record<string, string>>;
503
+ /**
504
+ * A readonly array of allowed hostnames.
505
+ */
506
+ readonly allowedHosts: Readonly<string[]>;
501
507
  }
502
508
  /**
503
509
  * Manifest for a specific Angular server application, defining assets and bootstrap logic.
@@ -653,67 +659,6 @@ declare function extractRoutesAndCreateRouteTree(options: {
653
659
  errors: string[];
654
660
  }>;
655
661
 
656
- /**
657
- * Defines a handler function type for transforming HTML content.
658
- * This function receives an object with the HTML to be processed.
659
- *
660
- * @param ctx - An object containing the URL and HTML content to be transformed.
661
- * @returns The transformed HTML as a string or a promise that resolves to the transformed HTML.
662
- */
663
- type HtmlTransformHandler = (ctx: {
664
- url: URL;
665
- html: string;
666
- }) => string | Promise<string>;
667
- /**
668
- * Defines the names of available hooks for registering and triggering custom logic within the application.
669
- */
670
- type HookName = keyof HooksMapping;
671
- /**
672
- * Mapping of hook names to their corresponding handler types.
673
- */
674
- interface HooksMapping {
675
- 'html:transform:pre': HtmlTransformHandler;
676
- }
677
- /**
678
- * Manages a collection of hooks and provides methods to register and execute them.
679
- * Hooks are functions that can be invoked with specific arguments to allow modifications or enhancements.
680
- */
681
- declare class Hooks {
682
- /**
683
- * A map of hook names to arrays of hook functions.
684
- * Each hook name can have multiple associated functions, which are executed in sequence.
685
- */
686
- private readonly store;
687
- /**
688
- * Registers a new hook function under the specified hook name.
689
- * This function should be a function that takes an argument of type `T` and returns a `string` or `Promise<string>`.
690
- *
691
- * @template Hook - The type of the hook name. It should be one of the keys of `HooksMapping`.
692
- * @param name - The name of the hook under which the function will be registered.
693
- * @param handler - A function to be executed when the hook is triggered. The handler will be called with an argument
694
- * that may be modified by the hook functions.
695
- *
696
- * @remarks
697
- * - If there are existing handlers registered under the given hook name, the new handler will be added to the list.
698
- * - If no handlers are registered under the given hook name, a new list will be created with the handler as its first element.
699
- *
700
- * @example
701
- * ```typescript
702
- * hooks.on('html:transform:pre', async (ctx) => {
703
- * return ctx.html.replace(/foo/g, 'bar');
704
- * });
705
- * ```
706
- */
707
- on<Hook extends HookName>(name: Hook, handler: HooksMapping[Hook]): void;
708
- /**
709
- * Checks if there are any hooks registered under the specified name.
710
- *
711
- * @param name - The name of the hook to check.
712
- * @returns `true` if there are hooks registered under the specified name, otherwise `false`.
713
- */
714
- has(name: HookName): boolean;
715
- }
716
-
717
662
  /**
718
663
  * Options for configuring an `AngularServerApp`.
719
664
  */
@@ -931,98 +876,6 @@ declare class InlineCriticalCssProcessor extends BeastiesBase {
931
876
  private conditionallyInsertCspLoadingScript;
932
877
  }
933
878
 
934
- /**
935
- * Angular server application engine.
936
- * Manages Angular server applications (including localized ones), handles rendering requests,
937
- * and optionally transforms index HTML before rendering.
938
- *
939
- * @remarks This class should be instantiated once and used as a singleton across the server-side
940
- * application to ensure consistent handling of rendering requests and resource management.
941
- */
942
- declare class AngularAppEngine {
943
- /**
944
- * A flag to enable or disable the rendering of prerendered routes.
945
- *
946
- * Typically used during development to avoid prerendering all routes ahead of time,
947
- * allowing them to be rendered on the fly as requested.
948
- *
949
- * @private
950
- */
951
- static ɵallowStaticRouteRender: boolean;
952
- /**
953
- * Hooks for extending or modifying the behavior of the server application.
954
- * These hooks are used by the Angular CLI when running the development server and
955
- * provide extensibility points for the application lifecycle.
956
- *
957
- * @private
958
- */
959
- static ɵhooks: Hooks;
960
- /**
961
- * The manifest for the server application.
962
- */
963
- private readonly manifest;
964
- /**
965
- * A map of supported locales from the server application's manifest.
966
- */
967
- private readonly supportedLocales;
968
- /**
969
- * A cache that holds entry points, keyed by their potential locale string.
970
- */
971
- private readonly entryPointsCache;
972
- /**
973
- * Handles an incoming HTTP request by serving prerendered content, performing server-side rendering,
974
- * or delivering a static file for client-side rendered routes based on the `RenderMode` setting.
975
- *
976
- * @param request - The HTTP request to handle.
977
- * @param requestContext - Optional context for rendering, such as metadata associated with the request.
978
- * @returns A promise that resolves to the resulting HTTP response object, or `null` if no matching Angular route is found.
979
- *
980
- * @remarks A request to `https://www.example.com/page/index.html` will serve or render the Angular route
981
- * corresponding to `https://www.example.com/page`.
982
- */
983
- handle(request: Request, requestContext?: unknown): Promise<Response | null>;
984
- /**
985
- * Handles requests for the base path when i18n is enabled.
986
- * Redirects the user to a locale-specific path based on the `Accept-Language` header.
987
- *
988
- * @param request The incoming request.
989
- * @returns A `Response` object with a 302 redirect, or `null` if i18n is not enabled
990
- * or the request is not for the base path.
991
- */
992
- private redirectBasedOnAcceptLanguage;
993
- /**
994
- * Retrieves the Angular server application instance for a given request.
995
- *
996
- * This method checks if the request URL corresponds to an Angular application entry point.
997
- * If so, it initializes or retrieves an instance of the Angular server application for that entry point.
998
- * Requests that resemble file requests (except for `/index.html`) are skipped.
999
- *
1000
- * @param request - The incoming HTTP request object.
1001
- * @returns A promise that resolves to an `AngularServerApp` instance if a valid entry point is found,
1002
- * or `null` if no entry point matches the request URL.
1003
- */
1004
- private getAngularServerAppForRequest;
1005
- /**
1006
- * Retrieves the exports for a specific entry point, caching the result.
1007
- *
1008
- * @param potentialLocale - The locale string used to find the corresponding entry point.
1009
- * @returns A promise that resolves to the entry point exports or `undefined` if not found.
1010
- */
1011
- private getEntryPointExports;
1012
- /**
1013
- * Retrieves the entry point for a given URL by determining the locale and mapping it to
1014
- * the appropriate application bundle.
1015
- *
1016
- * This method determines the appropriate entry point and locale for rendering the application by examining the URL.
1017
- * If there is only one entry point available, it is returned regardless of the URL.
1018
- * Otherwise, the method extracts a potential locale identifier from the URL and looks up the corresponding entry point.
1019
- *
1020
- * @param url - The URL of the request.
1021
- * @returns A promise that resolves to the entry point exports or `undefined` if not found.
1022
- */
1023
- private getEntryPointExportsForUrl;
1024
- }
1025
-
1026
879
  /**
1027
880
  * Function for handling HTTP requests in a web environment.
1028
881
  *
@@ -1055,5 +908,5 @@ type RequestHandlerFunction = (request: Request) => Promise<Response | null> | n
1055
908
  */
1056
909
  declare function createRequestHandler(handler: RequestHandlerFunction): RequestHandlerFunction;
1057
910
 
1058
- export { AngularAppEngine, PrerenderFallback, RenderMode, createRequestHandler, provideServerRendering, withAppShell, withRoutes, InlineCriticalCssProcessor as ɵInlineCriticalCssProcessor, destroyAngularServerApp as ɵdestroyAngularServerApp, extractRoutesAndCreateRouteTree as ɵextractRoutesAndCreateRouteTree, getOrCreateAngularServerApp as ɵgetOrCreateAngularServerApp, getRoutesFromAngularRouterConfig as ɵgetRoutesFromAngularRouterConfig, setAngularAppEngineManifest as ɵsetAngularAppEngineManifest, setAngularAppManifest as ɵsetAngularAppManifest };
911
+ export { PrerenderFallback, RenderMode, createRequestHandler, provideServerRendering, withAppShell, withRoutes, InlineCriticalCssProcessor as ɵInlineCriticalCssProcessor, destroyAngularServerApp as ɵdestroyAngularServerApp, extractRoutesAndCreateRouteTree as ɵextractRoutesAndCreateRouteTree, getOrCreateAngularServerApp as ɵgetOrCreateAngularServerApp, getRoutesFromAngularRouterConfig as ɵgetRoutesFromAngularRouterConfig, setAngularAppEngineManifest as ɵsetAngularAppEngineManifest, setAngularAppManifest as ɵsetAngularAppManifest };
1059
912
  export type { RequestHandlerFunction, ServerRoute, ServerRouteClient, ServerRouteCommon, ServerRoutePrerender, ServerRoutePrerenderWithParams, ServerRouteServer };