Using Web Components in React: The Complete Guide for Seamless Integration
Last updated 2 months, 2 weeks ago | 122 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
ref
andaddEventListener
to 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.