The three parts of Web Components
Web Components is not a single API but a set of three browser standards that work together.
Custom elements
Custom elements let you register a new HTML tag with its own behaviour:
class RecommendationWidget extends HTMLElement {
connectedCallback() {
this.render();
}
render() {
this.innerHTML = `<div class="reco-list">...</div>`;
}
}
customElements.define('recommendation-widget', RecommendationWidget);
Once registered, <recommendation-widget> behaves like a standard element in any HTML document.
Shadow DOM
Shadow DOM creates an isolated DOM subtree. CSS inside the shadow root does not clash with the
global styles of the host page:
class RecommendationWidget extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
/* These styles will not leak out onto the main page */
.title { font-size: 18px; color: #333; }
</style>
<div class="title">Similar products</div>
`;
}
}
This is the key advantage when distributing personalization widgets: the widget looks the same on
sites with very different CSS architectures.
HTML templates
The <template> element declares markup that is not rendered until it is explicitly cloned.
<slot> lets outside content be inserted at defined points inside the component — the equivalent of
props in React.
When Web Components are the right choice
| Scenario | Web Components | React / Vue |
|---|---|---|
| A widget for clients on different stacks | ✓ Preferable | ✗ Needs coordination |
| A SaaS widget with style isolation | ✓ Shadow DOM | ✗ Global styles clash |
| A complex internal application | Less convenient | ✓ Ecosystem and tooling |
| Maximum performance | ✓ No framework overhead | Depends on the implementation |
Web Components in personalization platforms
For SaaS platforms that distribute recommendation or onsite personalization widgets, Web Components
solve a structural problem: clients use different frameworks, versions and bundlers. A widget built
on plain custom elements plus shadow DOM embeds in a single line:
<script src="https://platform.example/widget.js"></script>
<recommendation-widget placement="pdp" strategy="similar-items"></recommendation-widget>
That lowers the integration barrier for clients with unusual stacks and reduces the load on the
platform’s own development team, which no longer has to maintain separate SDKs for React, Vue and
Angular.
Tip: shadow DOM does not inherit the host page’s CSS variables by default. If the widget needs
to be themed to match the client’s site, pass CSS variables in through attributes, and use
mode: 'open'with care.