You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: fragment-include-explainer.md
+66-61Lines changed: 66 additions & 61 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,49 +20,32 @@ The proposed [Declarative Out-of-order streaming specification](https://github.c
20
20
21
21
## Proposed solution
22
22
23
-
Proposing to extend the `<template>` element to support native, client-side HTML includes and dynamic content updates by introducing the `active` attribute, as well as fetching attributes (`src`, `crossorigin`, `referrerpolicy`, `nonce`, `integrity`, `blocking`).
23
+
We propose extending the `<template>` element to support native, client-side HTML includes and dynamic content updates by introducing the `for`, `src`, `async`, `buffered`, and `sanitize` attributes.
24
24
25
25
### Activation Model and Modes
26
-
The operational mode of the `<template>` element is explicitly declared and activated using the `active` attribute
27
-
which accepts a space-separated list of configuration tokens (represented as a `DOMTokenList` in JS):
28
-
-**`buffered`**: Parses content into a detached buffer and renders it atomically on stream completion.
29
-
-**`unsafe`**: Disables sanitization, allowing full HTML fragment parsing and script execution.
30
-
-**`async`**: Configures the network fetch (`src` present) to be asynchronous and non-blocking relative to document parsing.
31
26
27
+
An HTML `<template>` is active if it has a `for` attribute, a `src` attribute, or both. If both attributes are absent, it behaves as a classic inert template.
32
28
33
-
#### Default `active` Resolution
34
-
To determine the template's activation state and delivery/safety modes, the browser resolves the `active` token list using the following ordered algorithm:
35
-
36
-
1.**If the `active` attribute is explicitly present**:
37
-
Use the declared token list (e.g. `active=""` resolves to streaming, sanitized; `active="buffered"` resolves to buffered, sanitized).
38
-
2.**Else if the `src` attribute is present**:
39
-
Resolve the activation state to **`""`** (streaming, sanitized).
40
-
3.**Else if the `for` attribute is present**:
41
-
Resolve the activation state to **`"unsafe"`** (streaming, unsanitized, matching existing "patching" behavior).
42
-
4.**Otherwise**:
43
-
Resolve to **`null`** (inert classic template behavior).
44
-
45
-
46
-
Targeting is controlled via the `for` attribute:
47
-
-**Targeted Activation (`for="target-name"`)**:
29
+
#### Targeting and Placement
30
+
-**Targeted Include (`for="target-name"`)**:
48
31
Applies the template content to a targeted range (`<?start name="target-name">...<?end>`) or insertion point (`<?marker name="target-name">`). Content is inserted **before** the `<?end>` or `<?marker>` node.
49
-
-**In-place Activation (omitted or empty `for` with active template)**:
50
-
Inserts the content in-place at the template's position in the HTML stream.
32
+
-**In-place Include (omitted `for`or empty `for=""` / `for`)**:
33
+
Inserts the content in-place at the template's position in the HTML stream. If `for` is omitted entirely but `src` is present, it defaults to an in-place include.
51
34
52
35
```html
53
-
<!-- Inert template (legacy behavior, does not render) -->
36
+
<!-- Inert template (does not render) -->
54
37
<templateid="menu-tpl">
55
38
<li>Menu Item</li>
56
39
</template>
57
40
58
-
<!-- Active in-place rendering (streaming, sanitized) -->
59
-
<templateactive>
41
+
<!-- Active in-place rendering (inline streaming, unsafe by default) -->
42
+
<templatefor>
60
43
<p>Renders progressively in-place.</p>
61
44
</template>
62
45
63
-
<!-- Active in-place rendering (buffered, sanitized) -->
64
-
<templateactive="buffered">
65
-
<p>Renders atomically once fully parsed.</p>
46
+
<!-- Active in-place rendering (buffered, unsafe by default) -->
47
+
<templateforbuffered>
48
+
<p>Renders atomically once inline parsing is complete.</p>
66
49
</template>
67
50
68
51
<!-- Targeted rendering (streaming, unsafe by default) -->
@@ -73,76 +56,97 @@ Targeting is controlled via the `for` attribute:
73
56
<p>Streams contents directly into the gallery section.</p>
<p>Inserts atomically once comments are fully parsed.</p>
63
+
<templatefor="comments-patch"bufferedsanitize>
64
+
<p>Inserts atomically once comments are fully parsed, with scripts stripped.</p>
82
65
</template>
83
66
```
84
67
85
-
During active non-targeted template processing (streaming or buffered), the browser temporarily attaches the `<template>` element to the DOM at its declared position to act as the parser's insertion anchor. Incoming content is parsed and inserted directly **before** the template element. Once parsing/streaming completes (network EOF or closing tag), the template element is detached and removed, leaving **zero DOM footprint** in the final tree.
68
+
During active in-place template processing (streaming or buffered), the browser temporarily attaches the `<template>` element to the DOM at its declared position to act as the parser's insertion anchor. Incoming content is parsed and inserted directly **before** the template element. Once processing completes (network EOF or closing tag), the template element is detached and removed, leaving **zero DOM footprint** in the final tree.
86
69
87
70
### Resource Fetching and Script Attributes
71
+
88
72
When the `src` attribute is present, the template fetches its HTML payload over the network.
- Reuses `<script>`'s other network configuration attributes: `blocking`, `nonce`, `crossorigin`, and `referrerpolicy`. Async/non-blocking behavior is controlled directly by the `async` token in the `active` token list.
73
+
-**`async` (boolean)**: Configures the network fetch to be asynchronous and non-blocking relative to document parsing. If absent, the fetch is blocking (synchronous include).
74
+
- Reuses `<script>`'s other network configuration attributes: `blocking`, `nonce`, `crossorigin`, and `referrerpolicy`.
91
75
76
+
```html
77
+
<!-- Synchronous blocking in-place include (sanitized by default) -->
78
+
<templatesrc="header.html"></template>
79
+
80
+
<!-- Asynchronous non-blocking targeted include (sanitized by default) -->
If the `buffered` token is absent (e.g. `<template active>`), content is progressively parsed and inserted into the live DOM before the marker/template anchor.
96
-
-**Buffered (`active="buffered"`)**:
97
-
The browser parses the content directly into the template's own `content` DocumentFragment property. Once parsing completes, the sanitized contents of this DocumentFragment are cloned and inserted in a single batch.
98
88
89
+
The delivery mode is configured using the boolean `buffered` attribute:
90
+
-**Streaming (Default, `buffered` absent)**:
91
+
Content is progressively parsed and inserted into the live DOM before the marker/template anchor as network chunks arrive.
92
+
-**Buffered (`buffered` present)**:
93
+
The browser parses the content directly into the template's own `content` DocumentFragment property. Once parsing completes, the sanitized contents of this DocumentFragment are cloned and inserted in a single atomic update.
99
94
100
95
```html
101
96
<!-- 1. Streaming (Progressive Render) -->
102
97
<!-- In-place: elements render as they arrive from network -->
103
-
<templateactivesrc="feed-stream.html"></template>
98
+
<templatesrc="feed-stream.html"async></template>
104
99
105
100
<!-- Targeted: rows stream progressively into tbody without foster-parenting -->
-**Explicitly Activated (`active` present)**: **Sanitized by default**. To disable sanitization and execute scripts, include the `unsafe` token in the `active` token list.
127
-
-**Implicitly Activated (`for` present, `active` omitted)**: **Unsafe by default** (implicitly resolves to `active="unsafe"`), matching standard patching behavior.
121
+
122
+
Security safety is configured via the `sanitize` attribute, which accepts either an empty value (`sanitize` or `sanitize=""`) or `sanitize="unsafe"`.
123
+
124
+
#### Default Safety Resolution
125
+
To optimize security and compatibility, the default safety behavior is determined by the presence of the `src` attribute:
126
+
1.**External Includes (`src` is present)**: **Sanitized by default**.
127
+
- If `sanitize` is omitted, it defaults to safe sanitization.
128
+
- To execute scripts, the author must explicitly opt-out with `sanitize="unsafe"`.
129
+
2.**Inline Templates (`src` is absent)**: **Unsafe by default**.
130
+
- If `sanitize` is omitted, script execution is allowed (preserving compatibility with standard patching behavior).
131
+
- To enable sanitization on inline content, the author must explicitly declare `sanitize`.
128
132
129
133
```html
130
-
<!--Explicit active: sanitized by default (scripts stripped) -->
<!--Implicit active: unsafe by default (script runs) -->
143
+
<!--Inline: unsafe by default (script runs) -->
140
144
<templatefor="gallery">
141
145
<script>alert(1)</script>
142
146
</template>
143
147
144
-
<!--Implicit active, but sanitized: explicit active (without unsafe) overrides default -->
145
-
<templatefor="gallery"active>
148
+
<!--Inline but sanitized: explicit sanitize attribute overrides default -->
149
+
<templatefor="gallery"sanitize>
146
150
<div>User input: <script>alert(1)</script></div>
147
151
</template>
148
152
```
@@ -151,10 +155,10 @@ When the `src` attribute is present, the template fetches its HTML payload over
151
155
To allow granular security configuration for declarative includes, this proposal integrates with Content Security Policy (CSP):
152
156
153
157
1.**`fragment-src` Directive (New):**
154
-
Governs which origins are allowed to serve HTML subresources fetched via `<template active src="url">`. Fallback defaults to `default-src`.
155
-
Since standard active templates (without the `unsafe` token) are sanitized by default (scripts stripped), pages can allow a relaxed `fragment-src` policy (e.g. allowing third-party CDNs or CMS domains) without exposing themselves to script-execution vulnerabilities.
158
+
Governs which origins are allowed to serve HTML subresources fetched via `<template src="url">`. Fallback defaults to `default-src`.
159
+
Since standard active templates (without `sanitize="unsafe"`) are sanitized by default (scripts stripped), pages can allow a relaxed `fragment-src` policy (e.g. allowing third-party CDNs or CMS domains) without exposing themselves to script-execution vulnerabilities.
156
160
2.**`script-src` Enforcement:**
157
-
If a template includes the `unsafe` token (e.g. `<template active="unsafe" src="...">`), any inline `<script>` tags parsed from the fetched HTML must pass standard `script-src` policies (e.g. nonce or hash checks) to be allowed to execute.
161
+
If a template includes `sanitize="unsafe"`, any inline `<script>` tags parsed from the fetched HTML must pass standard `script-src` policies (e.g. nonce or hash checks) to be allowed to execute.
158
162
159
163
## Performance
160
164
@@ -254,10 +258,10 @@ This makes errors or latency difficult to observe, unlike the `<template>` based
254
258
255
259
10.**Do features in this specification enable new script execution/loading mechanisms?**
256
260
Yes. By importing external HTML subresources, the feature allows loading and parsing HTML which may contain scripts.
257
-
**Mitigation:** The proposal enforces security-by-default for explicitly activated templates. Explicitly declaring `active` (e.g. `<template active src="...">`) enables HTML sanitization by default, stripping out all script tags and event handler attributes before DOM insertion. To execute scripts, authors must explicitly opt-out of sanitization by including the `unsafe` token in the `active` token list (e.g., `active="unsafe"`).
261
+
**Mitigation:** The proposal enforces security-by-default for external resource includes. When `src` is present, HTML sanitization is enabled by default, stripping out all script tags and event handler attributes before DOM insertion. To execute scripts, authors must explicitly opt-out of sanitization by setting `sanitize="unsafe"`.
258
262
Furthermore, fetching external templates is governed by Content Security Policy (CSP):
259
-
* The new **`fragment-src`** directive controls which origins are allowed to serve HTML payloads for active templates. Because templates are sanitized by default, sites can configure a relaxed `fragment-src` policy for trusted CDN content without allowing script-injection paths.
260
-
* If `unsafe` is declared, any inline `<script>` tags loaded from the template must strictly comply with the document's standard **`script-src`** directives (e.g., matching nonce/hash).
263
+
* The new **`fragment-src`** directive controls which origins are allowed to serve HTML payloads for active templates. Because external templates are sanitized by default, sites can configure a relaxed `fragment-src` policy for trusted CDN content without allowing script-injection paths.
264
+
* If `sanitize="unsafe"` is declared, any inline `<script>` tags loaded from the template must strictly comply with the document's standard **`script-src`** directives (e.g., matching nonce/hash).
261
265
262
266
263
267
11.**Do features in this specification allow an origin to access other devices?**
@@ -270,11 +274,12 @@ This makes errors or latency difficult to observe, unlike the `<template>` based
270
274
N/A.
271
275
272
276
14.**How does this specification distinguish between behavior in first-party and third-party contexts?**
273
-
Subresources fetched via `<template active src="...">` are subject to standard Cross-Origin Resource Sharing (CORS) rules. Cross-origin templates require CORS headers to be read.
277
+
Subresources fetched via `<template src="...">` are subject to standard Cross-Origin Resource Sharing (CORS) rules. Cross-origin templates require CORS headers to be read.
274
278
275
279
15.**How do the features in this specification work in the context of a browser’s Private Browsing or Incognito mode?**
276
280
Standard subresource caching and partitioning rules apply.
277
281
282
+
278
283
16.**Does this specification have both "Security Considerations" and "Privacy Considerations" sections?**
279
284
Yes, these will be integrated into the HTML Standard.
0 commit comments