title: Is it possible to programmatically slot elements in web components?
body: <p>Is it possible to automatically or programmatically slot nested web components or elements of a specific type without having to specify the <code>slot</code> attribute on them?</p>
  <p>Consider some structure like this:</p>
  <pre class="lang-html prettyprint-override"><code>&lt;parent-element&gt;
    &lt;child-element&gt;Child 1&lt;/child-element&gt;
    &lt;child-element&gt;Child 2&lt;/child-element&gt;
  
    &lt;p&gt;Content&lt;/p&gt;
  &lt;/parent-element&gt;
  </code></pre>
  <p>With the <code>&lt;parent-element&gt;</code> having a Shadow DOM like this:</p>
  <pre class="lang-html prettyprint-override"><code>&lt;div id=&quot;child-elements&quot;&gt;
    &lt;slot name=&quot;child-elements&quot;&gt;
      &lt;child-element&gt;Default child&lt;/child-element&gt;
    &lt;/slot&gt;
  &lt;/div&gt;
  &lt;div id=&quot;content&quot;&gt;
    &lt;slot&gt;&lt;/slot&gt;
  &lt;/div&gt;
  </code></pre>
  <p>The expected result is:</p>
  <pre class="lang-html prettyprint-override"><code>&lt;parent-element&gt;
    &lt;#shadow-root&gt;
      &lt;div id=&quot;child-elements&quot;&gt;
        &lt;slot name=&quot;child-elements&quot;&gt;
          &lt;child-element&gt;Child 1&lt;/child-element&gt;
          &lt;child-element&gt;Child 2&lt;/child-element&gt;
        &lt;/slot&gt;
      &lt;/div&gt;
      &lt;div id=&quot;content&quot;&gt;
        &lt;slot&gt;
          &lt;p&gt;Content&lt;/p&gt;
        &lt;/slot&gt;
      &lt;/div&gt;
  &lt;/parent-element&gt;
  </code></pre>
  <p>In words, I want to enforce that <code>&lt;child-element&gt;</code>s are only allowed within a <code>&lt;parent-element&gt;</code> similar to <code>&lt;td&gt;</code> elements only being allowed within a <code>&lt;tr&gt;</code> element. And I want them to be placed within the <code>&lt;slot name=&quot;child-elements&quot;&gt;</code> element. Having to specify a <code>slot</code> attribute on each of them to place them within a specific slot of the <code>&lt;parent-element&gt;</code> seems redundant.
  At the same time, the rest of the content within the <code>&lt;parent-element&gt;</code> should automatically be slotted into the second <code>&lt;slot&gt;</code> element.</p>
  <p>I've first searched for a way to define this when registering the parent element, though <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define" rel="noreferrer"><code>CustomElementRegistry.define()</code></a> currently only supports <code>extends</code> as option.</p>
  <p>Then I thought, maybe there's a function allowing to slot the elements manually, i.e. something like <code>childElement.slot('child-elements')</code>, but that doesn't seem to exist.</p>
  <p>I've then tried to achive this programmatically in the constructor of the parent element like this:</p>
  <pre class="lang-js prettyprint-override"><code>constructor() {
    super();
  
    this.attachShadow({mode: 'open'});
    this.shadowRoot.appendChild(template.content.cloneNode(true));
  
    const childElements = this.getElementsByTagName('child-element');
    const childElementSlot = this.shadowRoot.querySelector('[name=&quot;child-elements&quot;]');
    for (let i = 0; i &lt; childElements.length; i++) {
      childElementSlot.appendChild(childElements[i]);
    }
  }
  </code></pre>
  <p>Though this doesn't move the child elements to the <code>&lt;slot name=&quot;child-elements&quot;&gt;</code>, so all of them still get slotted in the second <code>&lt;slot&gt;</code> element.</p>