What Are Web Components — Complete Guide
In this tutorial, you will learn about What Are Web Components. We cover key concepts, practical examples, and best practices to help you master this topic.
Web Components are reusable custom HTML elements built with browser-native APIs — Custom Elements, Shadow DOM, and HTML Templates — that work in any framework or no framework at all.
What You'll Learn
- The three Web Component technologies: Custom Elements, Shadow DOM, HTML Templates
- How Web Components differ from framework components
- Browser support and Polyfill options
- When to use Web Components vs React/Vue/Angular components
Why It Matters
Framework fragmentation is a major pain point. Components built with React do not work in Vue. Web Components solve this by using browser-native APIs. A single component works everywhere — React, Vue, Angular, Svelte, or vanilla HTML.
Real-World Use
- YouTube uses Web Components for its video player
- GitHub uses Custom Elements for its time-ago display
- Adobe Spectrum design system uses Web Components
- Salesforce Lightning components are Web Component-based
flowchart LR A[Web Components] --> B[Custom Elements] A --> C[Shadow DOM] A --> D[HTML Templates] B --> E[Define new HTML tags] C --> F[Style/DOM encapsulation] D --> G[Reusable markup] E --> H[customElements.define] F --> I[attachShadow] G --> J[template.content.cloneNode]
The Three Technologies
Web Components combine three browser APIs. Each serves a specific purpose.
// 1. Custom Elements: Define new HTML tags
class MyComponent extends HTMLElement {
constructor() {
super();
console.log('Custom element created');
}
connectedCallback() {
console.log('Element added to DOM');
}
}
customElements.define('my-component', MyComponent);
// 2. Shadow DOM: Encapsulation
class ShadowComponent extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
p { color: blue; } /* Scoped to shadow */
</style>
<p>Encapsulated content</p>
`;
}
}
customElements.define('shadow-component', ShadowComponent);
// 3. HTML Templates: Reusable markup
// <template id="my-template">
// <div class="card">
// <h3><slot name="title"></slot></h3>
// <p><slot></slot></p>
// </div>
// </template>
// Used together, these three APIs create complete components
Expected output: <my-component> logs creation. <shadow-component> renders with blue text unaffected by global CSS. Templates provide efficient cloning.
Web Components vs Framework Components
Understanding the differences helps choose the right approach.
// Framework component (React example)
// function MyButton({ label, onClick }) {
// return <button onClick={onClick}>{label}</button>;
// }
// Only works in React apps
// Web Component equivalent
class MyButton extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
button { padding: 8px 16px; background: #3498db; color: white; border: none; border-radius: 4px; cursor: pointer; }
button:hover { background: #2980b9; }
</style>
<button><slot></slot></button>
`;
this.shadowRoot.querySelector('button')
.addEventListener('click', () => {
this.dispatchEvent(new CustomEvent('btn-click'));
});
}
}
customElements.define('my-button', MyButton);
// Works in ANY HTML context:
// <my-button>Click Me</my-button>
// In React: <my-button>Click Me</my-button>
// In Vue: <my-button>Click Me</my-button>
Expected output: The custom button works identically in any framework. Clicking it dispatches a btn-click custom event that any framework can listen to.
Browser Support
Web Components are supported in all modern browsers.
// Check support
const supportsCustomElements = 'customElements' in window;
const supportsShadowDOM = !!HTMLElement.prototype.attachShadow;
const supportsTemplates = 'content' in document.createElement('template');
console.log('Custom Elements:', supportsCustomElements);
console.log('Shadow DOM:', supportsShadowDOM);
console.log('Templates:', supportsTemplates);
if (supportsCustomElements && supportsShadowDOM && supportsTemplates) {
console.log('Web Components fully supported');
} else {
console.log('Consider a polyfill: @webcomponents/webcomponentsjs');
}
// For older browsers, use the webcomponents polyfill:
// npm install @webcomponents/webcomponentsjs
// import '@webcomponents/webcomponentsjs/webcomponents-bundle';
Expected output: All three checks return true in modern browsers. The console shows full support.
When to Use Web Components
Web Components are ideal for certain scenarios.
// GOOD for Web Components:
// 1. Design system components (buttons, inputs, modals)
// 2. Third-party embeddable widgets
// 3. Cross-framework shared components
// 4. Simple presentational components
// BAD for Web Components:
// 1. Complex state management (no built-in reactivity)
// 2. Large component trees (no virtual DOM optimization)
// 3. SSR-dependent components (limited SSR support)
// 4. Components needing fine-grained reactivity
// Trade-offs
console.log('Web Components pros:');
console.log('- Framework agnostic');
console.log('- Native browser support');
console.log('- Style encapsulation');
console.log('- No build step required');
console.log('Web Components cons:');
console.log('- No data binding');
console.log('- No reactivity system');
console.log('- Limited SSR');
console.log('- Verbose compared to framework components');
Expected output: The console lists the pros and cons. Web Components excel at reusable UI primitives that must work across different frameworks.
Common Mistakes
- Using Web Components for everything — They are not a framework replacement. Use them for reusable UI primitives, not for application-level architecture.
- Forgetting to register the custom element —
customElements.define()must be called before the element appears in HTML. Otherwise, it renders as an unknown element. - Not handling lifecycle properly — Failing to clean up event listeners in disconnectedCallback causes memory leaks.
- Expecting framework-like reactivity — Web Components do not have built-in data binding. You must manually update the DOM when attributes change.
- Ignoring Accessibility — Custom elements need proper ARIA attributes, keyboard support, and focus management just like native elements.
Practice Questions
- What three technologies make up Web Components? Custom Elements, Shadow DOM, and HTML Templates.
- What problem do Web Components solve? Framework interoperability — components that work in any framework or no framework.
- How do you define a custom HTML element? Create a class extending HTMLElement and call
customElements.define('tag-name', ClassName). - Challenge: Create a Web Component that displays the current time and updates every second. It should work when embedded in any HTML page or framework.
FAQ
Mini Project
Build a simple profile card Web Component. The card should display a name, title, avatar image (from a URL attribute), and a bio slot. Style it with Shadow DOM. Test it in a plain HTML file and also in a minimal React or Vue app to verify cross-framework compatibility.
What's Next
Continue with Lesson 2: Custom Elements Basics to learn how to define and register custom HTML elements.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro