Repository navigation
Description
Which @angular/* package(s) are the source of the bug?
platform-server
Is this a regression?
No
Description
During SSR, a property binding ends up as el[name] = value on the domino element. When domino doesn't define that
property, the value is stored as a plain JavaScript property and never reaches the HTML. The browser shows that HTML
until hydration, and content in @defer (hydrate never) keeps it for good.
<button popovertarget="tip">Info</button>
<div id="tip" [popover]="'auto'">Popover content</div>
<fieldset [inert]="true">
<input placeholder="Locked" />
</fieldset>
<meter [max]="100" [value]="42"></meter>Server output:
<button popovertarget="tip">Info</button>
<div id="tip">Popover content</div>
<fieldset>
<input placeholder="Locked" />
</fieldset>
<meter value="42"></meter>So until the app hydrates, the popover content shows up inline and the button doesn't open it, the fieldset accepts
input, and the meter is drawn full (42 against the default max of 1).
To see how far this goes, I compared every property in the compiler's DOM schema with what domino defines, and kept
the ones Chrome reflects to an attribute. Leaving out obsolete elements, the main ones are:
- all elements:
popover,inert,autofocus,autocapitalize,inputMode(domino definesautoFocusand
autoCapitalize, so the standard names don't match) img:decodingvideo:playsInline,disablePictureInPicture, anddisableRemotePlaybackon media elementsbuttonandinput:popoverTargetAction;input:formActionmeter:min,max,low,high,optimumtdandth:headers
A few others are lost too, like contentEditable, slot, part and token lists such as relList.
#71470 adds command, name on details, autocorrect, webkitdirectory and rel on form to the schema, and they
hit the same problem. It leaves fetchPriority out for this reason: a priority hint that only arrives after hydration
is too late.
While looking at this, I also found that button, fieldset, label, meter, object, output and progress
share a single property object in domino's htmlelts.js. Each of them inherits the reflected attributes of the ones
defined before it, so fieldset.type returns "submit" and progress has formAction and data.
I opened angular/domino#54, which fixes all of the above. With it, the server output of the template above has
popover="auto", inert="" and max="100".
Please provide a link to a minimal reproduction of the bug
There's no StackBlitz since this is about the server output. In any SSR app, add the template above and look at the
page source, or call renderApplication() with it.
Please provide the exception or error you saw
No error with an AOT build: the attributes are just missing from the server HTML.
Please provide the environment you discovered this bug in (run ng version)
Angular: 22.2.3 (@angular/platform-server bundles domino 1929b1e, same as main)
Node: 24.21.0
Anything else?
This is the same kind of problem as #69785, which was fixed in angular/domino#34. Once the domino version is bumped
here, fetchPriority on img and link could be added to the schema.
Activity
JeanMeche commentedon Oct 24, 2026
While it's true that standard browsers reflect popover, inert, and max from IDL properties to content attributes, Angular's template binding model fundamentally targets DOM properties (el[name] = value), not HTML attributes.
Domino was designed as a lightweight DOM for SSR serialization, not a full WHATWG IDL compliance engine. Trying to manually maintain browser reflection parity in Domino for every newly standardized property is an endless maintenance burden.
Furthermore, several of these properties (like popoverTargetElement or commandForElement) take element references in IDL, which cannot be reflected to HTML attributes anyway.
For properties that are strictly 1:1 reflected attributes needed for initial SSR render (like popover or inert), updating Domino's reflection definitions may be a practical fix for now, but we should be cautious about adding complex spec-validation getters (e.g. clamping meter values or parsing command keywords) into Domino.