This content originally appeared on Go Make Things and was authored by Go Make Things
As part of my build-out of Kelp’s web component library, I had a problem.
I was create two components that might conflict with each other. Or they might not. It really depended on the order in which they instantiated.
Today, I want to share how I sorted it out. Let’s dig in!
The problem: two components in conflict
Kelp has two web components that interact with headings on the page.
<kelp-toc>
creates a table of contents dynamically from headings and their text.<kelp-heading-achors>
wraps headings in a link, and adds a styled icon to make it clear that it’s interactive.
If you wrap a page in the <kelp-heading-anchors>
component, all of the headings get a hash icon (#
) added to the end of them.
So this…
<kelp-heading-anchors>
<h2>Ahoy!</h2>
<h2>Shiver me timbers</h2>
</kelp-heading-anchors>
Becomes something like this (simplified version)…
<kelp-heading-anchors>
<h2 id="ahoy">
<a href="#ahoy">
Ahoy! #
</a>
</h2>
<h2 id="shiver-me-timbers">
<a href="#shiver-me-timbers">
Shiver me timbers #
</a>
</h2>
</kelp-heading-anchors>
Meanwhile, the <kelp-toc>
component grabs the text and IDs from heading elements and creates a table of contents.
Using the previous headings as an example, this…
<kelp-toc></kelp-toc>
Becomes this…
<kelp-toc>
<ul class="list-inline">
<li><a href="#ahoy">Ahoy!</a></li>
<li><a href="#shiver-me-timbers">Shiver me timbers</a></li>
</ul>
</kelp-toc>
But…
If <kelp-toc>
instantiates first, the HTML looks like the example above.
But if <kelp-heading-anchors>
instantiates first, the heading text is wrapped in a link and has a hash icon. The table of contents ends up looking like this instead…
<kelp-toc>
<ul class="list-inline">
<li>
<a href="#ahoy">
<a href="#ahoy">Ahoy! #</a>
</a>
</li>
<li>
<a href="#shiver-me-timbers">
<a href="#shiver-me-timbers">Shiver me timbers #</a>
</a>
</li>
</ul>
</kelp-toc>
You’re not seeing things, and that’s not a typo.
A link nested in a link, and the icon that’s really only supposed to be on the headings is now part of the table of contents text.
Instantiation order matters a lot here.
The fix
I figured web components would instantiate in the order they were included in the DOM.
<kelp-toc>
<kelp-heading-anchors>
<!-- TOC instantiates first -->
</kelp-heading-anchors>
</kelp-toc>
<kelp-heading-anchors>
<kelp-toc>
<!-- Heading Anchors instantiates first -->
</kelp-toc>
</kelp-heading-anchors>
👆 This assumption is wrong!
Patrick Nelson shared with me that web components instantiate in the order their customElements.define()
methods are called in JavaScript.
// TOC always instantiates first
customElements.define('kelp-toc', kelpTocClass);
customElements.define('kelp-heading-anchors', kelpHeadingAnchorsClass);
// Heading Anchors always instantiates first
customElements.define('kelp-heading-anchors', kelpHeadingAnchorsClass);
customElements.define('kelp-toc', kelpTocClass);
The HTML source order doesn’t matter.
This is more-or-less how CSS works, too (but in reverse). The last value declared in the CSS wins, regardless of how the values appear in the HTML.
Fixing this problem, then, is really easy! As long as the kelp-toc
component is defined first, you can setup the HTML however you want and the rendered HTMl will always work the way you’d expect.
Like this? A Lean Web Club membership is the best way to support my work and help me create more free content.
This content originally appeared on Go Make Things and was authored by Go Make Things

Go Make Things | Sciencx (2025-07-30T14:30:00+00:00) What order do web components instantiate in?. Retrieved from https://www.scien.cx/2025/07/30/what-order-do-web-components-instantiate-in/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.