Skip to content

Conversation

@KurtCattiSchmidt
Copy link

@KurtCattiSchmidt KurtCattiSchmidt commented Dec 2, 2025

Updates the definition of modulepreload to support as="style" and as="json" for preloading style and JSON module scripts respectively. Also removes as=json for rel=preload, as the only use for preloading JSON is for a module import, so it might as well directly add it to the module graph via modulepreload. There were some inconsistencies with the existing spec's supported as values for rel=preload, which this PR fixes with the introduction of a "preload destination" concept, which includes all supported types.

Fixes #10233

(See WHATWG Working Mode: Changes for more details.)


/acknowledgements.html ( diff )
/indices.html ( diff )
/links.html ( diff )
/semantics.html ( diff )

@KurtCattiSchmidt KurtCattiSchmidt changed the title Expanding <link type="modulepreload"> to allow "style" and "json" in as attribute Allow "style" and "json" in as attribute in modulepreload Dec 2, 2025
@KurtCattiSchmidt KurtCattiSchmidt changed the title Allow "style" and "json" in as attribute in modulepreload Allow "style" and "json" in as attribute for modulepreload Dec 2, 2025
Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also disallow "json" for <link rel=preload>?

@KurtCattiSchmidt
Copy link
Author

Should we also disallow "json" for <link rel=preload>?

You're right, "json" doesn't really make sense in preload if it's supported for modulepreload. I think this should be handled separately though, because WebKit recently added support for <link rel=preload as=json>, and we can have both for some window of time.

Filed #11995 to track and discuss separately.

@annevk
Copy link
Member

annevk commented Dec 8, 2025

I'd rather tackle them together as I have a feeling #11995 will not be addressed anytime soon otherwise. And it would be good to have that infrastructure in place as we add more types, such as text and bytes.

@KurtCattiSchmidt
Copy link
Author

I assumed there would be some window of overlap between the new and deprecated version, which is why I filed a separate bug. But if we can do them in one shot that's great. This feature is a little different in that it's not directly observable, so it does seem safe to just deprecate.

I'll update this PR to remove <link type="preload" as="json"> today.

@rniwa - you recently added support for <link type="preload" as="json"> in WebKit so your input here is appreciated.

@KurtCattiSchmidt
Copy link
Author

KurtCattiSchmidt commented Dec 8, 2025

Latest push handles removing "json" for "preload". I also added the implementation bugs. I'll work on tests next.

@KurtCattiSchmidt
Copy link
Author

Tests and MDN PR's have been are added, so the only missing part in compliance above is "two implementors are interested". @rniwa - can you give a WebKit position in https://bugs.webkit.org/show_bug.cgi?id=303761?

@bakkot
Copy link
Contributor

bakkot commented Dec 11, 2025

Note that the set of module types might be expanding - there's active proposals for text and bytes imports from JS.

@KurtCattiSchmidt
Copy link
Author

@annevk - you mentioned a missing conformance section for the as attribute, but I don't see an existing section for it, just https://html.spec.whatwg.org/#attr-link-as. Is this something I should add? Or is the table I edited in this PR under https://html.spec.whatwg.org/#attributes-3 sufficient?

@annevk
Copy link
Member

annevk commented Dec 17, 2025

@KurtCattiSchmidt those are the conformance requirements. You'll have to adjust the wording there to make it clear json is not a valid potential destination. Maybe something like:

Each potential destination except for "json" is a keyword for this attribute ...

Or maybe define preload destination as a concept which takes care of that.

@KurtCattiSchmidt
Copy link
Author

Thanks @annevk - it was awkward updating "potential destination" to exclude "json" everywhere, so I added a preload destination concept. This reduced some duplication elsewhere too.

@cwilso cwilso added the agenda+ To be discussed at a triage meeting label Dec 18, 2025
source Outdated
@@ -16396,18 +16390,23 @@ interface <dfn interface>HTMLLinkElement</dfn> : <span>HTMLElement</span> {

<hr>

A <dfn data-x="concept-preload-destination">preload destination</dfn> is a <span
data-x="concept-potential-destination">potential destination</span>, excluding "<code
data-x="">json</code>" when used with <code data-x="rel-preload">preload</code> links, and is
Copy link

@smaug---- smaug---- Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excluding a single thing this way is a bit icky special case, and special cases tend to cause issues later. Would there be some other way to express this (if we need to exclude json. Not sure why we need to, but perhaps it doesn't matter too much.).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might have to exclude more module destination types going forward. One way to avoid this would be to refactor Fetch's destination concept to have subtypes or some such. But not sure we need to go there right away.

Copy link
Author

@KurtCattiSchmidt KurtCattiSchmidt Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a "preload destination" concept in the latest push that instead lists all supported module types (in addition to the "module preload destination" concept added for module preloads).

@noamr
Copy link
Collaborator

noamr commented Dec 18, 2025

Should we also disallow "json" for <link rel=preload>?

It's already disallowed. See https://html.spec.whatwg.org/multipage/links.html#translate-a-preload-destination
It's probably enough to add json and style to modulepreload specifically.

@KurtCattiSchmidt
Copy link
Author

KurtCattiSchmidt commented Dec 18, 2025

Should we also disallow "json" for <link rel=preload>?

It's already disallowed. See https://html.spec.whatwg.org/multipage/links.html#translate-a-preload-destination It's probably enough to add json and style to modulepreload specifically.

Not exactly, https://html.spec.whatwg.org/#consume-a-preloaded-resource lists JSON as a preload destination. I reverted to the prior commit in this PR, which removes that part and adds "style" and "json" to modulepreload. Does this version look correct @noamr?

@KurtCattiSchmidt
Copy link
Author

The latest push addresses everything discussed this morning (returned conformance section, listed all supported values as a "preload destination" concept).

source Outdated
data-x="">audio</code>", "<code data-x="">fetch</code>", "<code data-x="">font</code>", "<code
data-x="">image</code>", "<code data-x="">style</code>", "<code data-x="">track</code>", "<code
data-x="">video</code>", or a <span
data-x="concept-script-like-destination">script-like destination</span>.
Copy link
Collaborator

@noamr noamr Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a change in behavior. Do we know if e.g. <link rel=preload as="sharedworker"> works or supposed to work?
I see that the test variants don't cover this.
Maybe keep it as script and we can check if it works for other script-like destinations separately?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

@KurtCattiSchmidt KurtCattiSchmidt Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Consume a Preloaded Resource" section lists all script-like destinations as supported: https://html.spec.whatwg.org/#consume-a-preloaded-resource

(it's in step 6 of "For the purposes of this section, a string type matches a string destination if the following algorithm returns true:" under "If any of the following are true:...")

Copy link
Author

@KurtCattiSchmidt KurtCattiSchmidt Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think limiting it to "script" would be a change in behavior given the above. But perhaps that is incorrect and it should be "script" there instead of "script-like destination". Note that Chrome logs an error that it's valid but unsupported with "sharedworker" (see the links here #11981 (comment)).

source Outdated
destination</span>. For other <code>link</code> elements, it must not be specified.</p>
have a value which is a <span
data-x="concept-module-preload-destination">module preload destination</span>. For other
<code>link</code> elements, it must not be specified.</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this quite works. Initially when we introduce the attribute we should say it takes either a preload or module preload destination. Then we should say that each destination of the union of these destinations is a keyword, mapping to a state of the same name. Otherwise the enumerated attribute definition doesn't work.

Then we restrict per rel attribute value what keywords are valid.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, this is much clearer now. I moved "This is an enumerated attribute" to be before listing the valid values. It was a little awkward phrasing "the union of..." but I think the latest version is decent.

source Outdated
@@ -29009,13 +28985,16 @@ document.body.appendChild(wbr);</code></pre>
data-x="concept-request-credentials-mode">credentials mode</span>.</p>
</div>

A <dfn data-x="concept-preload-destination">preload destination</dfn> is "<code
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per above, I had to remove the "concept-" prefix for this to compile. This revealed that there's already a definition for "preload destination" that listed a string, which I changed to point to the full list of preload destinations.

Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great @KurtCattiSchmidt, thanks for tidying it all up. @smaug---- @noamr any final thoughts?

I suggest we merge this Monday next week.

@noamr
Copy link
Collaborator

noamr commented Jan 15, 2026

This looks great @KurtCattiSchmidt, thanks for tidying it all up. @smaug---- @noamr any final thoughts?

I suggest we merge this Monday next week.

Re-read the PR, looks good to me!

@KurtCattiSchmidt
Copy link
Author

This looks great @KurtCattiSchmidt, thanks for tidying it all up. @smaug---- @noamr any final thoughts?
I suggest we merge this Monday next week.

Re-read the PR, looks good to me!

@noamr - would you mind hitting the +1 button again? You had previously approved, but it reset when I re-requested review.

@cwilso cwilso removed the agenda+ To be discussed at a triage meeting label Jan 15, 2026
@KurtCattiSchmidt
Copy link
Author

This looks great @KurtCattiSchmidt, thanks for tidying it all up. @smaug---- @noamr any final thoughts?

I suggest we merge this Monday next week.

Thanks Anne! We have a holiday on Monday so I'll plan on landing on Tuesday unless any new issues arise.

@annevk
Copy link
Member

annevk commented Jan 16, 2026

The editors will take care of the merging (and are available on Monday). Unless you wanted to push it back one day? Though it wouldn't give the US an extra day so then we'd have to merge Wednesday.

@KurtCattiSchmidt
Copy link
Author

If someone else is merging then Monday is fine with me, thanks for checking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Support json/style as modulepreload destinations

7 participants