salesforce / lwc

⚡️ LWC - A Blazing Fast, Enterprise-Grade Web Components Foundation
https://lwc.dev
Other
1.63k stars 395 forks source link

Allow native `<template>`s in LWC template files #3657

Open nolanlawson opened 1 year ago

nolanlawson commented 1 year ago

Right now, if you want an actual <template> element, you can't put it in an LWC template HTML file:

<template>
    <h1>Hello world!</h1>
    <template></template>
</template>

This throws an error:

Error: LWC1077: Invalid template tag. A directive is expected to be associated with the template tag.

The reason is generally because the LWC framework expects <template>s to be used for LWC-specific things like for-loops, scoped slots, etc.

There are valid use cases, though, for someone to want an actual <template> tag. (E.g. maybe they are creating third-party custom elements inside of LWC components.) We could potentially support this, e.g. with a directive like lwc:native-template or something.

Workaround

For now, the workaround for using actual <template> tags is to put them in .js files instead of .html files. E.g.:

<template>
  <div lwc:dom="manual" lwc:ref="container"></div>
</template>
const myTemplate = document.createElement('template')
this.refs.container.appendChild(myTemplate)
shaundr commented 1 year ago

We ran into this issue at Trailhead when attempting to wrap Coveo Atomic UI with LWC.

nolanlawson commented 1 year ago

Actually, it just occurred to me that we probably don't need a special directive for this. If we're throwing an error on a <template> without a directive today, then we can just make any <template> without a directive into a plain <template> element.

The two exceptions are probably lwc:ref and lwc:inner-html – those actually make sense for a <template> element. lwc:spread is debatable but may be supportable. We'd probably have to do an audit of all directives that make sense here.

nolanlawson commented 1 year ago

Interesting issue: if you put an LWC component inside of a <template>:

<template>
  <x-foo></x-foo>
</template>

...then we should probably log a warning, since this will not work if you try to do something like template.cloneNode(true), due to our UpgradableConstructor.

N.B. that Coveo seems to use <template>s inside of web component slotted content.

MamataLV commented 10 months ago

Hi @nolanlawson, Can I pick up this issue?

nolanlawson commented 10 months ago

@MamataLV It is marked "up for grabs," so sure! 🙂

nolanlawson commented 10 months ago

For a v1 of this feature, I would suggest just treating any <template> without an lwc:* directive as a plain <template> element. We can figure out details like lwc:ref and lwc:inner-html later.