Skip to content

Web Component with Templates, Slots, and Shadow DOM Not Working #12322

@robertsosinski

Description

@robertsosinski

Astro Info

Astro                    v5.0.0-beta.4
Node                     v22.9.0
System                   macOS (arm64)
Package Manager          npm
Output                   server
Adapter                  @astrojs/node
Integrations             none

If this issue only occurs in one browser, which browser is a problem?

All Browsers

Describe the Bug

I have the following HTML page that uses a web component, template with slots, and shadow DOM.

<html>
  <head>
  </head>
  <body>
    <template id="custom-card-template">
      <h2><slot name="card-title">Default Card Title</slot></h2>
      <p><slot name="card-content">Default content goes here.</slot></p>
    </template>
    
    <custom-card>
      <span slot="card-title">My First Title</span>
      <span slot="card-content">This is my first card content!</span>
    </custom-card>
    
    <custom-card>
      <span slot="card-title">My Second Title</span>
      <span slot="card-content">This is my second card content!</span>
    </custom-card>
    
    <script>
      customElements.define('custom-card', class CustomCard extends HTMLElement {
        constructor() {
          super();
    
          const template = document.getElementById("custom-card-template");
          const templateContent = template.content;
    
          const shadowRoot = this.attachShadow({ mode: 'open' });
          shadowRoot.appendChild(templateContent.cloneNode(true));
        }
      });
    </script>
  </body>
</html>

In a plain .html file, it loads just fine (see first html.png snip). However in an .astro template, it first flashes with the raw <custom-card> nodes, then presents two copies of the <template>. I think what is happening is that the <slot> elements are getting replaced by Astro, and something else is happening whereas perhaps additional javascript loading is making for a "page jump" kinda effect.

See the following screen snips:

Expected behavior (this is a raw HTML file that I am serving locally):
html

Astro behavior (this is a .astro file that Astro is serving):
astro

What's the expected result?

It should look as the expected screen shot, showing two updated templates.

Link to Minimal Reproducible Example

https://gist.github.com/robertsosinski/e6b44c85fc8bca7b1ff8a49e45e601ce

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs triageIssue needs to be triaged

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions