← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Web Components

Frontend ES2018 Advanced
debt(d7/e5/b3/t5)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints list Lighthouse and Chrome DevTools, but these don't automatically flag misuse patterns like missing observedAttributes, premature DOM manipulation, or framework coupling. No automated linting is indicated ('automated: no'). Misuse is silent until runtime — attributeChangedCallback silently never fires, Shadow DOM blocks external CSS without warning — requiring careful manual review or runtime debugging.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix describes a conceptual architectural shift: replacing framework-tied or jQuery-based widgets with native Custom Elements. This involves rewriting component logic, adjusting PHP templates to emit the new element tags, and potentially restructuring theming (CSS custom properties for Shadow DOM). Not a one-liner, but not a full cross-cutting architectural rework either.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Web Components apply to the web context only, and once defined, a custom element is self-contained. The structural burden is localised — teams must follow the Custom Elements API conventions (constructor, connectedCallback, observedAttributes), but the rest of the codebase is largely unaffected. Shadow DOM encapsulation can impose a persistent theming tax but it stays within the component boundary.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap — a documented gotcha most devs eventually learn' (t5). The misconception field states developers assume Web Components require a framework, which is a well-documented but common wrong belief. Additionally, common_mistakes include several non-obvious gotchas: missing super() silently breaks the constructor, omitting observedAttributes silently disables attributeChangedCallback, and Shadow DOM's CSS blocking surprises developers expecting normal style inheritance. These are documented but not intuitive.

About DEBT scoring →

Also Known As

Custom Elements Shadow DOM HTML Templates

TL;DR

A suite of native browser APIs (Custom Elements, Shadow DOM, HTML Templates) for creating reusable, encapsulated HTML elements without frameworks.

Explanation

Web Components consist of three specs: Custom Elements (define new HTML tags with custom behaviour), Shadow DOM (encapsulated DOM subtree with scoped styles), and HTML Templates (<template> for inert markup). They work in all modern browsers without any build step or framework dependency. Shadow DOM provides true style encapsulation — styles inside do not leak out, styles outside do not leak in. Framework components (React, Vue) are built on similar concepts but require the framework to render.

Common Misconception

Web Components require a framework — they are native browser APIs that work in any HTML page without React, Vue, or Angular.

Why It Matters

Web Components enable truly reusable UI elements that work across frameworks — a custom <date-picker> works in a React app, a PHP-rendered page, or a plain HTML file.

Common Mistakes

  • Not calling super() in the Custom Element constructor — required before accessing 'this'.
  • Manipulating attributes before the element is connected to the DOM — use connectedCallback.
  • Not defining observed attributes with static get observedAttributes() — attributeChangedCallback never fires without it.
  • Forgetting that Shadow DOM style encapsulation blocks external CSS — use CSS custom properties for theming.

Code Examples

✗ Vulnerable
// Custom element without proper lifecycle:
class BadElement extends HTMLElement {
    constructor() {
        // Missing super() call
        this.innerHTML = '<p>Content</p>'; // DOM manipulation before connected
    }
}
✓ Fixed
class UserCard extends HTMLElement {
    static get observedAttributes() { return ['name', 'role']; }

    constructor() {
        super(); // Required
        const shadow = this.attachShadow({ mode: 'open' });
        shadow.innerHTML = `
            <style>:host { display: block; font-family: sans-serif; }</style>
            <div class="card"><slot name="name"></slot></div>
        `;
    }
    connectedCallback() { /* Element added to DOM */ }
    attributeChangedCallback(name, old, val) { /* Attribute changed */ }
}
customElements.define('user-card', UserCard);

Added 15 Mar 2026
Edited 22 Mar 2026
Views 40
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 2 pings F 0 pings S 1 ping S 1 ping M 1 ping T 2 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 7 Scrapy 5 Ahrefs 4 Google 4 Perplexity 3 Unknown AI 2 ChatGPT 2 Claude 2 Bing 2 Sogou 2 Meta AI 1 PetalBot 1
crawler 29 crawler_json 6
DEV INTEL Tools & Severity
🔵 Info ⚙ Fix effort: High
⚡ Quick Fix
Use Custom Elements to create reusable PHP-renderable HTML components — define once with customElements.define(), PHP renders <my-component> as plain HTML, JS upgrades it client-side
📦 Applies To
javascript ES2018 web
🔗 Prerequisites
🔍 Detection Hints
Complex jQuery widgets not reusable across PHP templates; framework component tied to specific JS framework when vanilla would work
Auto-detectable: ✗ No lighthouse chrome-devtools
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Medium Context: File Tests: Update


✓ schema.org compliant