{
    "slug": "web_components",
    "term": "Web Components",
    "category": "frontend",
    "difficulty": "advanced",
    "short": "A suite of native browser APIs (Custom Elements, Shadow DOM, HTML Templates) for creating reusable, encapsulated HTML elements without frameworks.",
    "long": "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.",
    "aliases": [
        "Custom Elements",
        "Shadow DOM",
        "HTML Templates"
    ],
    "tags": [
        "frontend",
        "javascript",
        "browser",
        "components"
    ],
    "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."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "html_semantic",
        "js_modules",
        "progressive_enhancement"
    ],
    "prerequisites": [
        "js_class_syntax",
        "html_semantic",
        "progressive_enhancement"
    ],
    "refs": [
        "https://developer.mozilla.org/en-US/docs/Web/API/Web_components"
    ],
    "bad_code": "// Custom element without proper lifecycle:\nclass BadElement extends HTMLElement {\n    constructor() {\n        // Missing super() call\n        this.innerHTML = '<p>Content</p>'; // DOM manipulation before connected\n    }\n}",
    "good_code": "class UserCard extends HTMLElement {\n    static get observedAttributes() { return ['name', 'role']; }\n\n    constructor() {\n        super(); // Required\n        const shadow = this.attachShadow({ mode: 'open' });\n        shadow.innerHTML = `\n            <style>:host { display: block; font-family: sans-serif; }</style>\n            <div class=\"card\"><slot name=\"name\"></slot></div>\n        `;\n    }\n    connectedCallback() { /* Element added to DOM */ }\n    attributeChangedCallback(name, old, val) { /* Attribute changed */ }\n}\ncustomElements.define('user-card', UserCard);",
    "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",
    "severity": "info",
    "effort": "high",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/web_components",
        "html_url": "https://codeclaritylab.com/glossary/web_components",
        "json_url": "https://codeclaritylab.com/glossary/web_components.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Web Components](https://codeclaritylab.com/glossary/web_components) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/web_components"
            }
        }
    }
}