How can I render a <template /> tag with react?

The reason is that JSX does a different job than what the <template /> tags exists for. The idea of a template tag is to not render its children and pretty much handle it like unparsed text (the browser actually parses it just to make sure its valid html, but does nothing more)

But when you write this in JSX:

return (
  <template>
    <div>some content</div>
  </template>
)

you're basically instructing react to create a 'template' element and then create a 'div' element and then to append this div to the template as a child.

So under hood this happens:

const template = document.createElement('template')
const div = document.createElement('div')
const text = document.createTextNode('some text')
div.appendChild(text)
template.appendChild(div)

But what you want is to set the contents of the <template /> as a string. You can use innerHTML for that.


Solution

One solution would be:

render() {
  return (
    <template
      dangerouslySetInnerHTML={{
        __html: '<div>some content</div>'
      }}
    />
  )
}

Now you're asking react to create all those children tags as node elements but letting the browser decide what to do with them.

Nicer solution

You might not want to use dangerouslySetInnerHTML all the time. So let's create a helper component:

function Template({ children, ...attrs }) {
  return (
    <template
      {...attrs}
      dangerouslySetInnerHTML={{ __html: children }}
    />
  );
}

Now any time you need to use a template you can use it like this:

render() {
  return (
    <Template>
      {'<div>some content</div>'}
    </Template>
  )
}

Don't forget to put the inner content in quotes, because it should be a string.