This is necessary to use SSR safely with `createApplication` and avoid constraining users to `bootstrapApplication`. It is one more step towards feature parity between `createApplication` and `bootstrapApplication`.
The existing implementation of `PlatformLocation` uses a custom URL parsing mechanism that can be brittle and doesn't properly update the `href` property. This change refactors the URL parsing to use the native `URL` constructor, providing more robust and accurate parsing of URLs, which also correctly updates the `href` property.
The tests for `PlatformLocation` have also been moved to a dedicated file to improve organization and clarity.
PR Close#64494
This updates tests and examples only to prepare for zoneless by default.
These changes were identified and made as part of #63382. Anything that
failed gets `provideZoneChangeDetection` unless the fixes were easily
and quickly determined.
It also adds the zoneless provider to the `initTestEnvironment` calls
for tests in this repo to prevent regressions before #63382 is merged.
PR Close#63668
This commit introduces a number of changes to the server bootstrapping process to make it more robust and less error-prone, especially for concurrent requests.
Previously, the server rendering process relied on a module-level global platform injector. This could lead to issues in server-side rendering environments where multiple requests are processed concurrently, as they could inadvertently share or overwrite the global injector state.
The new approach introduces a `BootstrapContext` that is passed to the `bootstrapApplication` function. This context provides a platform reference that is scoped to the individual request, ensuring that each server-side render has an isolated platform injector. This prevents state leakage between concurrent requests and makes the overall process more reliable.
BREAKING CHANGE:
The server-side bootstrapping process has been changed to eliminate the reliance on a global platform injector.
Before:
```ts
const bootstrap = () => bootstrapApplication(AppComponent, config);
```
After:
```ts
const bootstrap = (context: BootstrapContext) =>
bootstrapApplication(AppComponent, config, context);
```
A schematic is provided to automatically update `main.server.ts` files to pass the `BootstrapContext` to the `bootstrapApplication` call.
In addition, `getPlatform()` and `destroyPlatform()` will now return `null` and be a no-op respectively when running in a server environment.
PR Close#63562
This commit removes the use of the privately exported
PendingTasksInternal everywhere except for Router. A follow-up change
will be done to remove that one as well and delete the private export.
PR Close#61049
BREAKING CHANGE:
This commit deprecates `ng-reflect-*` attributes and updates the runtime to stop producing them by default. Please refactor application and test code to avoid relying on `ng-reflect-*` attributes.
To enable a more seamless upgrade to v20, we've added the `provideNgReflectAttributes()` function (can be imported from the `@angular/core` package), which enables the mode in which Angular would be producing those attribites (in dev mode only). You can add the `provideNgReflectAttributes()` function to the list of providers within the bootstrap call.
PR Close#60973
This change refactor how the dynamically created component
deals with attributes in order to reuse the existing
setupStaticAttributes logic (instead of having specific
and similar code).
PR Close#59572
This can happen if server providers are provided more than twice. We detect it on the state transfer phase by flagging app id as transferred in a set.
Resolves#58531
PR Close#58935
This commit removes a custom `whenStable` util in favor of standard `ApplicationRef.whenStable` API.
There is also an important different between the custom `whenStable` function and `ApplicationRef.whenStable` implementation: the `whenStable` was caching the "stable" promise on per-ApplicationRef basis, which resulted in unexpected behavior with zoneless, when some code ended up getting a stale resolved promise, when an application was not stable yet, this causing order of operations issues. This commit also has an extra test that covers that case.
PR Close#58834
This commit adds the `ngServerMode` as global, which allows for the tree-shaking of server-only code from the bundles. When this flag is unset at runtime, server-specific code will be excluded by Closure, optimizing bundle size.
**Internal Angular Flag:** This is an internal Angular flag (not a public API), avoid relying on it in application code.
PR Close#58386
This re-organizes the hydration tests to make it easier to add new tests. Incremental hydration can have tests in a separate file after this groundwork is landed.
PR Close#58196
The `bootstrap()` phase might fail e.g. due to an rejected promise in some `APP_INIIALIZER`.
If `PlatformRef` is not destroyed, then the main app's injector is not destroyed and therefore `ngOnDestroy` hooks of singleton services is not called on the end (failure) of SSR.
This could lead to possible memory leaks in custom SSR apps, if their singleton services' `ngOnDestroy` hooks contained an important teardown logic (e.g. unsubscribing from RxJS observable).
Note: I needed to fix by the way another thing too: now we destroy `moduleRef` when `platformInjector` is destroyed - by setting a `PLATFORM_DESTROY_LISTENER`
fixes#58111
PR Close#58112
BREAKING CHANGE:
Legacy handling or Node.js URL parsing has been removed from `ServerPlatformLocation`.
The main differences are;
- `pathname` is always suffixed with a `/`.
- `port` is empty when `http:` protocol and port in url is `80`
- `port` is empty when `https:` protocol and port in url is `443`
PR Close#54874
The InitialRenderPendingTasks currently attempts to only contribute to
ApplicationRef stableness one time to support SSR. This isn't actually
how the switchMap works in reality. This commit updates
the isStable observable to be more clear that it's always a combination
of the zone stableness and pending tasks.
In addition, this commit renames the service to just be PendingTasks
because it doesn't directly relate to rendering. While the purpose is
to track things that might cause rendering to happen, we don't know if the
tasks will affect rendering at all.
PR Close#53534
Prior to this commit relative HTTP requests were not being resolved to absolute even thought the behaviour is documented in https://angular.io/guide/universal#using-absolute-urls-for-http-data-requests-on-the-server.
This caused relative HTTP requests to fail when done on the server because of missing request context. This change is also required to eventually support HTTP requests handled during prerendering (SSG).
Closes#51626
PR Close#52326
This commit removes the `withNoDomReuse` function to minimize public API. The `withNoDomReuse` function used to disable DOM reuse, which is the main feature of the `provideClientHydration()`.
The `withNoDomReuse()` function was in the "developer preview" mode, so the removal happens without prior deprecation.
BREAKING CHANGE:
The `withNoDomReuse()` function was removed from the public API. If you need to disable hydration, you can exclude the `provideClientHydration()` call from provider list in your application (which would disable hydration features for the entire application) or use `ngSkipHydration` attribute to disable hydration for particular components. See this guide for additional information: https://angular.io/guide/hydration#how-to-skip-hydration-for-particular-components.
PR Close#52057
Prior to this change `this.isStable.pipe(first((isStable) => isStable)).toPromise()` had to be done in multiple places across the framework and the Angular CLI see https://github.com/angular/angular-cli/pull/25856#discussion_r1328158846. In the majority of cases an Observable based `isStable` API is not needed. This also removes the need for RXJS operator imports.
PR Close#51807
non-destructive hydration expects the DOM tree to have the same structure in both places.
With this commit, the app will throw an error if comments are stripped out by the http server (eg by some CDNs).
fixes#51160
PR Close#51170
Prior to this change in some cases errors tht happen during routing were not being surfaced. This is due to the fact that the router has floating promises, and the platform was being destroyed prior to these being settled.
PR Close#50587
This commit removes unnecessary transfer state escaping and updates this process to be done by the means of a `replacer` and `reviver` method as this removes the need to export the escaping and unescaping methods.
The only thing that we need to escape is `<script` and `</script` which are done by the browsers, but not Node.js.
PR Close#50201
Using `@angular/platform-browser-dynamic` is no longer required for JIT scenarios with Ivy. Instead `@angular/compiler` should be imported instead.
This change is part of the effort to reduce the server bundles sizes, which is needed to support cloud workers.
BREAKING CHANGE:
Users that are using SSR with JIT mode will now need to add `import to @angular/compiler` before bootstrapping the application.
**NOTE:** this does not effect users using the Angular CLI.
PR Close#50064
This commit updates the logic that adds the "ng-server-context" attribute to the root elements to also include information about SSR feature enabled got an application.
PR Close#49773
This commits adds `makeStateKey`, `StateKey` and `TransferState` methods in `@angular/core` as public API and deprecated the same exported symbols in `@angular/platform-browser`.
DEPRECATED: `makeStateKey`, `StateKey` and `TransferState` exports have been moved from `@angular/platform-browser` to `@angular/core`. Please update the imports.
```diff
- import {makeStateKey, StateKey, TransferState} from '@angular/platform-browser';
+ import {makeStateKey, StateKey, TransferState} from '@angular/core';
```
PR Close#49563
These two options where created for a feature which was never completed. https://github.com/angular/universal/pull/1860
Eventually these options should be added to `withTransferCache` HTTP logic.
DEPRECATED: `PlatformConfig.baseUrl` and `PlatformConfig.useAbsoluteUrl` platform-server config options are deprecated as these were not used.
PR Close#49546
This commit adds a background macrotask when an XHR request is performed. The macrotask is started during `loadstart` and ended during `loadend` event.
The macrotask is needed so that the application is not stabilized during HTTP calls. This is important for server rendering, as the application is rendering when the application is stabilized.
The application is stabilized when there are no longer pending Macro and Micro tasks intercepted by Zone.js, Since an XHR request is none of these, we create a background macrotask so that Zone.js is
made aware that there is something pending.
Prior to this change, we patched the `HttpHandler` in `@angular/platform-server` but this is not enough, as there can be multiple `HttpHandler` in an application, example when importing `HttpClient` in a lazy loaded component/module.
Which causes a new unpatched instance of `HttpHandler` to be created in the child injector which is not intercepted by Zone.js and thus the application is stabalized and rendered before the XHR request is finalized.
NB: Zone.js is fundamental for SSR and currently, it's not possible to do SSR without it.
Closes: #49425
PR Close#49546
This commit implements a simple tracker of the pending tasks during initial rendering. The class allows adding and removing tasks from the set. The class also exposes a promise that gets resolved once the last task is removed.
This tracker is needed to keep track of ongoing processes like Router navigation (and potentially HTTP requests) and acts as a signaling mechanism to SSR and hydration that the application is in the "stable" state and a serialization can be performed.
This class would also act as a future replacement for the `ApplicationRef.isStable` for zoneless applications.
PR Close#49576
This commit removes the `renderApplication` overload that accepts a root component as the first parameter.
BREAKING CHANGE:
`renderApplication` method no longer accepts a root component as first argument. Instead, provide a bootstrapping function that returns a `Promise<ApplicationRef>`.
Before
```ts
const output: string = await renderApplication(RootComponent, options);
```
Now
```ts
const bootstrap = () => bootstrapApplication(RootComponent, appConfig);
const output: string = await renderApplication(bootstrap, options);
```
PR Close#49463
`ng-app` is an AngularJS attribute, see https://docs.angularjs.org/api/ng/directive/ngApp. Using this attribute on a non AngularJS element can cause DI issues in AngularJS when running an AngularJS and Angular application on the same page.
As such, we avoid such problems the Angular `ng-app` attribute is renamed to `ng-app-id`.
PR Close#49424
This commit adds the `provideServerSupport()` function that returns the `EnvironmentProviders` needed to setup server rendering without NgModules.
PR Close#49380
Prior to this change component styles generated on the server where removed prior to the client side component being rendered and attached it's own styles. In some cases this caused flickering. To mitigate this `initialNavigation: enabledBlocking'` was introduced which allowed the remove of server styles to be defer to a latter stage when the application has finished initialization.
This commit changes the need for this, by not removing the server generated component styles and reuse them for client side rendering.
PR Close#48253