<template for>: letting HTML declare which region gets replaced

Chrome 150 supports the template for attribute: processing instructions mark replaceable regions, and streamed templates fill them. How it works, what it solves, and why it should not go anywhere near production yet.

Chrome 150 (30 June 2026) shipped support for <template for="…">. Edge 150 followed on 2 July. Firefox and Safari do not support it.

In one sentence: HTML can mark a region as “to be replaced later”, and a streamed <template> fills it in.

How it works

Positions are marked with processing instructions:

<p>Loading comments…</p>
<?marker name="comments">

A range instead of a point:

<?start name="feed">
  <p>placeholder</p>
<?end>

Then the server, without finishing the response, can keep pushing into the same stream:

<template for="comments">
  <p>First comment</p>
</template>

When the browser receives that template, it replaces the marked point (or the start/end range) named comments.

What it actually solves

This is not a new way to make pages interactive — there are plenty of those. It addresses a narrower, harder problem: during server-side streaming, the order in which content arrives is decided by the data sources, not by page position.

The classic bind:

  • The comments API is faster than the article, but comments sit below it
  • A sidebar “related posts” block waits on a search, while the main content was ready long ago
  • One slow endpoint blocks everything after it, because HTML must be emitted in order

Traditional streaming constrains you to order: whatever arrives first can only be written first. So you either make fast things wait for slow ones, or park fast content somewhere it will have to be moved from later.

<template for> decouples position from order: content may arrive at any moment in the stream, as long as it declares which marker it belongs to.

My take: do not use it yet

Three reasons:

  1. Chromium only. Firefox and Safari have nothing (Firefox tracks it as bug 2053472, so they know about it, with no timeline). You must design a fallback — and the fallback is usually “everything piles up at the bottom in arrival order”, which looks worse than not streaming at all.
  2. Roughly 0.06% of page loads. That number says it just landed: no established patterns, no tooling, no accumulated experience. Every problem you hit, you dig out yourself.
  3. The server has to cooperate. It needs your framework (or hand-written code) to keep pushing fragments into the response and to know each fragment’s marker name. This is not a capability you get from adding an attribute.

When to keep an eye on it

If your situation matches all of these, file it away:

  • The page has a lot of content from multiple sources — a news front page, a dashboard, an article with comments
  • Your slowest endpoint determines the wait after the first byte
  • You accept that “Chromium users get the better version, everyone else gets a complete static one”

That third point is the crux. It suits progressive enhancement naturally: unsupported browsers get content in source order. Nothing is missing; the order is merely suboptimal.

The part I care about more

The shape of this feature is worth noticing: it does not make JavaScript stronger. It makes “replace a region of content” something HTML can express by itself.

For over a decade, partial updates have been JavaScript’s territory — fetch data, find a node, swap innerHTML. The cost: before the script runs, that region either does not exist or is wrong.

<template for> moves it back to the HTML layer: the server emits replacement instructions directly, and the browser executes them natively, with no script involved. That is the same road as <details>, popover, and <dialog> — pushing common interactions down into declarative markup.

The value of that road is not the JavaScript you save. It is that “works without JavaScript” becomes a viable default again.

← Back to all posts

Comments

…