- <script> is the last tag before </head> close
- .appendChild is called before </head> (because document.body is undefined then)
- <script> tags with a src attribute and no specified type attribute should not write <script type="undefined" ...>
When users access the root route `/` without providing a locale, the application now redirects them to their preferred locale based on the `Accept-Language` header.
This enhancement leverages the user's browser preferences to determine the most appropriate locale, providing a seamless and personalized experience without requiring manual locale selection.
Enhance performance when using SSR by adding `modulepreload` links to lazy-loaded routes. This ensures that the required modules are preloaded in the background, improving the user experience and reducing the time to interactive.
Closes#26484
This commit introduces `ngServerMode` to ensure proper handling of external `@angular/` packages when they are used as externals during server-side rendering (SSR).
Closes: #29092
Previously, the `baseHref` option under each locale allowed for generating a unique base href for specific locales. However, users were still required to handle file organization manually, and `baseHref` appeared to be primarily designed for this purpose.
This commit introduces a new `subPath` option, which simplifies the i18n process, particularly in static site generation (SSG) and server-side rendering (SSR). When the `subPath` option is used, the `baseHref` is ignored. Instead, the `subPath` serves as both the base href and the name of the directory containing the localized version of the app.
Below is an example configuration showcasing the use of `subPath`:
```json
"i18n": {
"sourceLocale": {
"code": "en-US",
"subPath": ""
},
"locales": {
"fr-BE": {
"subPath": "fr",
"translation": "src/i18n/messages.fr-BE.xlf"
},
"de-BE": {
"subPath": "de",
"translation": "src/i18n/messages.de-BE.xlf"
}
}
}
```
The following tree structure demonstrates how the `subPath` organizes localized build output:
```
dist/
├── app/
│ └── browser/ # Default locale, accessible at `/`
│ ├── fr/ # Locale for `fr-BE`, accessible at `/fr`
│ └── de/ # Locale for `de-BE`, accessible at `/de`
```
DEPRECATED: The `baseHref` option under `i18n.locales` and `i18n.sourceLocale` in `angular.json` is deprecated in favor of `subPath`.
The `subPath` defines the URL segment for the locale, serving as both the HTML base HREF and the directory name for output. By default, if not specified, `subPath` will use the locale code.
Closes#16997 and closes#28967
This update addresses excessive log noise caused by the following warning:
`NG0912: Component ID generation collision detected. Components 'AppComponent' and 'AppComponent' with selector 'app-root' generated the same component ID. To fix this, you can change the selector of one of those components or add an extra host attribute to force a different ID. Find more at https://angular.dev/errors/NG0912`.
This commit ensures consistent behavior between `ng build` and `ng serve`. Previously, `ng serve` did not display an error message when Node.js built-in modules were included in browser bundles. By default, Vite replaces Node.js built-ins with empty modules, which can lead to unexpected runtime issues. This update addresses the problem by surfacing clear error messages, providing better developer feedback and alignment between the two commands.
Closes: #27425
TypeScript 5.6 and higher added functionality that will search for a
`package.json` file for source files that are part of the program (e.g., `.d.ts`)
and within a node modules directory. This can be an expensive tasks especially
considering the large amount of `.d.ts` files within packages. TypeScript supports
using a cache of known `package.json` files to improve the performance of this task.
The Angular CLI will now provide and reuse this cache across rebuilds during watch
mode. This includes the use of `ng serve`.
The performance difference is most apparent for the Angular template diagnostic
step of the build. Internally the Angular compiler creates a new template typechecking
program which causes the `package.json` search process to occur. By leveraging the
cache, this process becomes a series of cache hits. In the event that files are modified
within the node modules directory, the cache is invalidated and the following rebuild
may be longer as a result.
When component template HMR support is enabled (`NG_HMR_TEMPLATES=1`),
TypeScript file changes will now be analyzed to determine if Angular component
metadata has changed and if the changes can support a hot replacement. Any
other changes to a TypeScript file will cause a full page reload to avoid
inconsistent state between the code and running application. The analysis
currently has an upper limit of 32 modified files at one time to prevent
a large of amount of analysis to be performed which may take longer than
a full rebuild. This value may be adjusted based on feedback. Component
template HMR is currently experimental and may not support all template
modifications. Both inline and file-based templates are now supported.
However, rebuild times have not yet been optimized.
The `deployUrl` option was unintentionally being prepended to preload
links with absolute URLs within the generated index HTML for an appplication.
This has now been corrected and absolute URLs will not be altered when a
deploy URL is configured.
The `define` option will now apply to JavaScript that is included in the output
via the `scripts` option. This allows the replacement of identifiers within any
included scripts in addition to the already supported replacement within application
code.
Whlist, this package is not really optional, NPM will install the wrong verson of peer dependencies when the Angular CLI is in prerelease mode.
```ts
STDERR:
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: test-project@0.0.0
npm error Found: @angular/animations@19.1.0-next.0
npm error node_modules/@angular/animations
npm error @angular/animations@"^19.1.0-next.0" from the root project
npm error
npm error Could not resolve dependency:
npm error peer @angular/animations@"19.0.1" from @angular/platform-server@19.0.1
npm error node_modules/@angular/platform-server
npm error peer @angular/platform-server@"^19.1.0-next.0 || ^19.0.0" from @angular/ssr@19.1.0-next.0
npm error node_modules/@angular/ssr
npm error @angular/ssr@"19.1.0-next.0" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
```
When using the `ng add` command, the package version selection logic was not correctly selected based on the available versions in desc order. This could lead to selecting an unintended version of the package.
Closes: #28985
Updated the `Http2ServerResponse` interface to eliminate dependency on generics, ensuring compatibility across multiple versions of `@types/node`.
Closes#28965
When using the `application` builder, the `fileReplacements` option will
now work as it previous did with the `browser` builder when replacing
JSON files.
Ensure that parameterized routes do not cause errors when the `getPrerenderParams` function is undefined, specifically in cases where the routing API is not utilized.
Closes#28948
To minimize downstream breakage for consumers of the private API, the
`createCompilerPlugin` function signature has been adjusted to maintain
compatibility with v18.
Resolved an issue where the use of `esbuild`'s `inject` feature caused incorrect reordering of class structures during bundling. This reordering affected extended classes, as illustrated below:
```js
class e extends Ur {
constructor(n, r, i) {
super(n, r, i);
}
ngOnDestroy() {
this.flush();
}
static ɵfac = function (r) {
return new (r || e)(pe(Xe), pe(Ti), pe(Di));
};
static ɵprov = oe({ token: e, factory: e.ɵfac });
}
var Ur = class {
// Class properties and methods omitted for brevity
};
```
By reducing the reliance on `inject`, we ensure that the ordering of class properties and methods remains consistent, preserving the expected behavior.
Closes#28941
This commit ensures proper handling of nested redirects that are implicitly structured but not explicitly defined in the router configuration.
Closes#28903
Stackblitz appears to fail when attempting to use `crypto.createHash` with
an algorithm value of `sha-256`. Since Node.js supports both the hyphenated
and unhyphenated values, the later is now used to avoid issues when running
on Stackblitz.
Ensure that errors occurring during initialization are properly propagated,
as Piscina currently swallows errors during worker initialization.
For more details, see:
b647472334/src/worker.ts (L57)
The Angular AOT compilation logic for a rebuild has been updated to include
infrastructure for additional checks of stale TypeScript files against updated
files. The actual comparison aspects have not yet been implement and no behavior
changes are yet present for template HMR.