Using Web Components in React: The Complete Guide for Seamless Integration
Last updated 4 months, 2 weeks ago | 389 views 75 5
Introduction: Why Use Web Components in React?
Modern web development is increasingly component-driven. React leads the way in building reusable UI components, but it exists within the JavaScript ecosystem, not the browser’s native API.
That’s where Web Components come in.
Web Components are a browser-native way to define reusable UI elements using HTML, JavaScript, and CSS—independent of any framework.
By integrating Web Components in React, you get:
-
Reusability across frameworks (Vue, Angular, etc.)
-
Better encapsulation with Shadow DOM
-
True native interoperability
This article shows how to use Web Components inside React apps, deal with common issues, and write clean, production-ready integrations.
What Are Web Components?
Web Components are a collection of web platform APIs that let you create custom, reusable, encapsulated HTML elements. They consist of:
| Feature | Description |
|---|---|
| Custom Elements | Define new HTML tags like <my-widget> |
| Shadow DOM | Encapsulate internal markup/styles |
| HTML Templates | Define markup in <template> for reuse |
| ES Modules | Structure and import/export logic |
Using Web Components in React: Step-by-Step
1. Create a Web Component (Vanilla JS)
Let’s define a simple <my-greeting> component:
// greeting-component.js
class MyGreeting extends HTMLElement {
connectedCallback() {
const name = this.getAttribute('name') || 'World';
this.innerHTML = `<p>Hello, ${name}!</p>`;
}
}
customElements.define('my-greeting', MyGreeting);
✅ This registers
<my-greeting>as a custom element.
2. Load the Web Component in React
First, import the Web Component script in your React app.
// App.js
import React from 'react';
import './greeting-component.js'; // Custom element definition
function App() {
return (
<div>
<h1>React with Web Components</h1>
{/* Use custom element like any other tag */}
<my-greeting name="React Dev"></my-greeting>
</div>
);
}
export default App;
React will render
<my-greeting>correctly as long as it’s registered before usage.
3. Passing Props to Web Components
You can pass attributes like this:
<my-greeting name="John" />
But: Web Components do not support JSX prop camelCasing or event handling the way React does. You must manually bridge them.
4. Listening to Events
Custom elements dispatch events using CustomEvent. React doesn’t natively catch these—you need useEffect or ref.
// greeting-component.js
this.dispatchEvent(new CustomEvent('greeted', { detail: { name } }));
// App.js
import React, { useEffect, useRef } from 'react';
import './greeting-component.js';
function App() {
const greetingRef = useRef();
useEffect(() => {
const handleGreet = (e) => {
console.log('Greeted:', e.detail.name);
};
const el = greetingRef.current;
el.addEventListener('greeted', handleGreet);
return () => {
el.removeEventListener('greeted', handleGreet);
};
}, []);
return <my-greeting ref={greetingRef} name="React" />;
}
export default App;
Full Example: React + Web Component
// greeting-component.js
class MyGreeting extends HTMLElement {
connectedCallback() {
const name = this.getAttribute('name') || 'World';
this.innerHTML = `<p>Hello, ${name}!</p>`;
this.dispatchEvent(new CustomEvent('greeted', { detail: { name } }));
}
}
customElements.define('my-greeting', MyGreeting);
// App.js
import React, { useRef, useEffect } from 'react';
import './greeting-component.js';
function App() {
const greetingRef = useRef();
useEffect(() => {
const el = greetingRef.current;
const handleGreeted = (e) => alert(`Greeted: ${e.detail.name}`);
el.addEventListener('greeted', handleGreeted);
return () => el.removeEventListener('greeted', handleGreeted);
}, []);
return (
<div>
<h1>React & Web Components</h1>
<my-greeting ref={greetingRef} name="React Dev" />
</div>
);
}
export default App;
⚠️ Tips & Common Pitfalls
✅ Tips
-
Always import the Web Component definition before rendering it.
-
Use
refandaddEventListenerto listen to custom events. -
Prefer attributes over props when passing values.
❌ Pitfalls
-
React does not auto-bind events on custom elements.
-
Don’t use camelCase props like
customProp; Web Components expect dash-case (custom-prop). -
Avoid rendering Web Components before they’re registered, or they’ll appear as empty tags.
Comparison: React Components vs Web Components
| Feature | React Component | Web Component |
|---|---|---|
| Lifecycle Management | React controlled | Browser controlled |
| Shadow DOM | Optional via libraries | Built-in support |
| Props/State | JSX + useState/props |
Attributes + internal state |
| Events | Synthetic Events (JSX) | CustomEvent via addEventListener |
| Reusability | React-only | Framework-agnostic |
Conclusion: When & Why to Use Web Components in React
Integrating Web Components in React offers the best of both worlds—framework-agnostic reusability and React’s robust UI architecture.
Use Web Components in React when:
-
Sharing UI across multiple frameworks
-
Using third-party UI libraries built with Web Components
-
You want better encapsulation via Shadow DOM
For most React-only projects, use native React components. But when you need interoperability, Web Components shine.
Key Takeaways
-
Web Components are natively supported and reusable across any framework.
-
React can render them easily but requires manual event and ref handling.
-
For full compatibility, bridge props, attributes, and events carefully.
-
Ideal for shared UI libraries, micro frontends, or design systems.