Several guides, examples, and the update-guide recommendations linked to
external resources over insecure http. Switch them to https.
(cherry picked from commit 28d59e8d63)
## Summary
This PR adds v22.x and v23 release dates. It also changes Angular's release cadence to a yearly cycle.
## Why we are making this change
The community has long requested less frequent major releases due to the impact of breaking changes and upgrades for their projects as well as for enterprise customers. Additionally, a longer release cycle provides increased API stability for developers using agentic workflows, while still delivering a reasonable cadence of API upgrades and migrations.
(cherry picked from commit 25dbe79507)
Aligns our clone of the navigation API types with the built-in TypeScript types. This is related to an internal issue.
(cherry picked from commit d79b3b65e9)
A leading UTF-8 byte order mark (U+FEFF) before the first `#` stops the
Markdown parser from recognizing the heading, so the guide renders its
title as a paragraph and drops the standard docs header. The character
is invisible, so it cannot be caught in review.
Add a check in the guides generation pipeline that throws when a source
file starts with a BOM, failing the build with the offending file name.
This sits alongside the existing unknown-anchor check and prevents the
regression fixed in #69889 from recurring.
The ng-container and binding template guide files each began with a
UTF-8 BOM (EF BB BF) before the leading `#`. The docs markdown parser
only promotes `#` to an H1 when it is the first character on the line,
so the BOM demoted the title to paragraph text (`<p># ...</p>`) and the
standard docs header (breadcrumbs, page title, edit button) never
rendered.
Stripping the BOM restores `#` as the first character, so both pages
now generate the proper `<header class="docs-header">` block. Verified
by rebuilding //adev/src/content/guide/templates:templates and
inspecting the generated HTML.
Fixes#69889
Separate direct from curried calls of `describe`/`it` modifiers
(direct: `skip`, `only`, etc.; curried: `runIf`, `each`, etc.)
and perform the required patching to them.
Fixes: #69748
Propagate the crossorigin attribute from priority NgOptimizedImage hosts to SSR-generated preload links. Keep preload and image requests in the same credentials mode to avoid an anonymous image issuing an earlier credentialed request.
Twitter is now X. In the custom-route-matcher guide, point the author-credit
link at x.com and refer to an "X (formerly Twitter) handle" (clarified once,
then "X handle"), matching the "X (formerly Twitter)" wording already used in
the footer, navigation, and update guide.
Store the trigger kind before each switch and assign the value to `never` in the fallback branch.
This removes the `any` casts and makes the switches exhaustive. Adding a new `DeferTriggerKind` without handling it in either phase now produces a TypeScript compilation error.
Runtime behavior and error messages remain unchanged.
The angle-guessing minigame's result popup personifies your score with a
hand-drawn stick-figure that changes expression by accuracy. Now that Angie
appears across adev — the 404 page, docs search, the embedded editor, the
tutorial intros and completions — give the minigame the same treatment so
its result feels consistent with the rest of the docs.
Replace the result reactor's stick-figure illustration with an Angie pose
keyed to accuracy (seven tiers, superhero down to angry). She is revealed
once the accuracy counter finishes counting up, popping in beside a speech
bubble that carries the round's existing quote. The result popup is widened
so Angie and the bubble sit side by side, and the share link is moved from
twitter.com to x.com.
This removes the previous hand-drawn stick-figure result art. NG the Angle,
the interactive character in the play area, is unchanged.
Previously, the `pending()` status on a field's `ValidationState` only checked if the field itself or its immediate children had a pending asynchronous validator by directly inspecting `asyncErrors()`. This meant that a pending asynchronous validator deep within a nested form (e.g. on a grand-child) would not correctly bubble the `pending` state up to the root form.
fixes#69840
Adds a compliance case pinning the instruction-set selection for a
directive-free standalone component:
- full compile: the compiler can prove the template has no directive
dependencies, so it takes the DOM-only fast path
(`ɵɵdomElementStart`/`ɵɵdomElementEnd`).
- local compile: the compiler cannot inspect dependencies, so
`hasDirectiveDependencies` is forced true and the full instruction
set is emitted (`ɵɵelementStart`/`ɵɵelementEnd`).
This mode-dependent switch was previously only exercised incidentally by
the `foreign_component` case, which couples it with foreign-component
compilation. The new case isolates it.
Currently, the SVG sanitizer checks a static set of candidate attribute
names (`attributeName` and `attributename`). This approach misses other case
variations (such as `attributenAme` or others), which could potentially
bypass sanitization when binding sensitive attributes like `href` on
`<set>` or `<animate>` elements.
This change retrieves all attribute names of the SVG element, performs a
case-insensitive comparison with `'attributename'`, and sanitizes the value
if a match is found.
The tutorial intro and "next steps" pages were plain headings with no
send-off. Bookend each tutorial with Angie: a greeting pose welcoming
learners on the intro page, and a superhero pose congratulating them on
the completion page, each beside a speech bubble.
The bubble treatment from the 404 page lived inside the not-found
component, so it's extracted into a reusable docs-content style
(docs-tutorial-mascot) usable from tutorial markdown, and applied to the
intro and completion pages of the Learn Angular, Signals, and Signal
Forms tutorials.
When only some NgClass usages are migrated (partial migration),
the NgClass import should be preserved in the module/component
imports if it is still used elsewhere.
The "Page Not Found" page always rendered the sentence "We have
initiated a search for the term extracted from the URL", but the
NotFound component only runs a search when a term can be extracted,
and only renders results when there is at least one hit. On a 404
with no extractable term or no matching results, the page asserted
a search it never backed up.
Gate the sentence behind the same searchResults() check that guards
the results list, so the empty state simply reads "We couldn't find
what you were looking for."
`makeCacheKey` joined the request fields with `|` before hashing. The url
and the serialized body can contain `|` themselves, so a shifted field
boundary (url `/items/a` + body `b|c` vs url `/items/a|b` + body `c`)
produced the same joined string and the same key, letting two distinct
requests share a transfer cache slot.
Join with `\0` instead, which cannot occur in a valid url or in encoded
params, so the field boundaries cannot be forged by field content.
The Angie illustrations on the DevTools empty-state screens (added in
#69786) shipped with an empty `alt` and `aria-hidden="true"`. Give them
descriptive alt text and drop `aria-hidden` to improve accessibility.
The MCP server setup guide linked to /ai/skills, which 404s. The
page lives at /ai/agent-skills. Update the link to point to the
correct route.
Fixes#69838
The Transfer State and signal-graph tabs render bare-text placeholders
when there's nothing to show. Add the Angie mascot to both, matching the
pattern already shipped on the top-level DevTools screens (#69786):
- Transfer State "isn't using Transfer State" card: replace the
swap_horiz icon with the teaching pose.
- Signal graph "No signals in this component": add the orthos-back pose
above the message.
The `inlineStyleLanguage` build option has existed since v12 but was
never listed in the workspace configuration reference. Add it to the
"Extra build and test options" table alongside the other style options,
documenting its accepted values (css, less, sass, scss) and default.
Fixes#69801