Better support <template> tags
See original GitHub issueHTML <template>
tag is used to pass reusable templates to web components.
However, at the moment this doesn’t work with React in a way that is useful to users.
Context: Basic usage of <template>
If you have HTML like this:
<template>
<p>Some Text</p>
</template>
You can then use this template with pure JS like this:
const template = document.querySelector("template")
const node = template.content.cloneNode(true)
document.append(node)
The important part here is the content
property of the template.
Whats the problem?
Writing the template code in HTML is OK. However, if you create the template DOM nodes with JS like this, it won’t work:
const template = document.createElement("template")
const p = document.createElement("p")
p.textContent = "Some Text"
template.appendChild(p)
In this case, the content
property of the template will be empty. Instead, one would have to do either of these:
const template = document.createElement("template")
template.innerHTML = "<p>Some Text</p>"
or
const template = document.createElement("template")
const p = document.createElement("p")
p.textContent = "Some Text"
template.content.appendChild(p) // notice `content`
The first does work because there is a special case in innerHTML
for template tags (see mdn).
The second example works because the <p>
DOM node is added directly to the content
of the template.
What does this has to do with React?
When using React to create the template, React is appending the generated DOM nodes directly to the template node and not to the content
property of the template node. For this reason at the moment you can’t really use template tags in React apps.
I have the impression that this is not the fault of React as the same problem exists for angular and most likely other spa frameworks too. Instead this looks like a misconception of the template
tag to me (mayby I’m wrong on this and there is a good reason for this behavior).
However, maybe React could do something to make this usecase less anoying? A possible solution could be to detect if the parent node is a template
and to add the child nodes to the content
property instead of the node itself. But I’m not sure if there would be any negative side-effects of this.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:3
- Comments:7
I’ve also been experiencing this issue. The browser’s native HTML parser constructs the
<template>
tag differently than regular DOM nodes. Natively, the browser appends all children to the template’scontent
fragment, instead of the template’s actual children. A template’schildren.length
should always be 0.It would be ideal if
react-dom
would copy this behavior when constructing<template>
tags.Here’s an example of native parsing versus React parsing: https://codesandbox.io/s/new-sun-8l62o?file=/src/App.tsx:1056-1118
As a workaround, you can patch some HTMLTemplateElement methods since those methods aren’t supposed to be called anyway (see the note of the HTML standard)