Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk5 min

How to Convert a React Component to a Web Component

Wrap an existing React component in a browser-native custom element, with a clear contract for inputs, events, lifecycle, and rendering.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To make a React component usable as a browser-native tag such as <profile-card>, keep the React component and wrap it in a custom element. The wrapper registers a hyphenated tag, creates a React root when connected, passes data through a defined interface, and unmounts the root when disconnected. This is an integration boundary—not a conversion of JSX into a different component implementation.

What the wrapper does

A Web Component is built from browser features, including custom elements and, optionally, Shadow DOM. For a React-backed custom element, the browser owns the outer tag while React renders the existing component into a child mount node. MDN describes an autonomous custom element as a class extending HTMLElement and registered with customElements.define() (MDN: Using custom elements).

The wrapper is responsible for translating between the browser-facing interface and the React component’s props and callbacks. Define that interface deliberately: markup attributes are strings, whereas JavaScript properties can carry objects, arrays, and other values.

Build a basic React-backed custom element

  1. Choose an autonomous custom-element name. Use a lowercase name containing a hyphen, such as profile-card.
  2. Extend HTMLElement and register the element. Call customElements.define('profile-card', ProfileCardElement) once the class is defined.
  3. Create a mount node and React root on connection. In connectedCallback(), add a child node, call createRoot(mount), then render the existing component.
  4. Pass inputs and expose events. Map supported attributes or properties to React props, and dispatch documented CustomEvents for events host pages need to handle.
  5. Unmount on disconnection. Call root.unmount() in disconnectedCallback() to let React detach from the container.

This illustrative JSX sketch shows the core pattern, not a production-ready implementation:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import React from 'react';
import { createRoot } from 'react-dom/client';
import ProfileCard from './ProfileCard.js';

class ProfileCardElement extends HTMLElement {
  connectedCallback() {
    if (this._root) return;

    const mount = document.createElement('div');
    this.append(mount);
    this._root = createRoot(mount);
    this._render();
  }

  disconnectedCallback() {
    this._root?.unmount();
    this._root = undefined;
  }

  set profile(value) {
    this._profile = value;
    this._render();
  }

  get profile() {
    return this._profile;
  }

  _render() {
    if (!this._root) return;

    this._root.render(
      <ProfileCard
        profile={this._profile}
        onSelect={(event) => {
          this.dispatchEvent(new CustomEvent('profile-select', {
            detail: event,
            bubbles: true,
            composed: true,
          }));
        }}
      />
    );
  }
}

customElements.define('profile-card', ProfileCardElement);

React’s createRoot reference explains that a root manages the DOM inside its container and that root.unmount() detaches React from it. The sketch renders only after connection; it does not cover every case a real wrapper must handle, including attributes, inputs assigned before connection, and repeated connection after disconnection.

Choose attributes or properties for inputs

Use attributes for string configuration

Attributes suit values that should be visible in HTML, such as an identifier, label, or display mode. They are strings, so parse and validate them where appropriate. To respond to changes, declare the observed attribute names with static get observedAttributes() and implement attributeChangedCallback(); custom-element lifecycle callbacks are described in MDN’s custom-element guide.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Use properties for rich JavaScript values

Assign objects and arrays as properties on the element rather than expecting them to work as HTML attributes. For example, a consumer can set element.profile = profileData. A robust wrapper should account for a property being set before connectedCallback() runs, then render the latest value when the React root is created.

React version matters when another React application renders the custom element. The React documentation for custom elements describes JSX values passed as attributes by default, and the React 19 release notes describe improved handling: on the client, React assigns a prop as a property when the custom-element instance has a matching property, and otherwise uses an attribute. Server rendering follows separate rules: primitive values such as strings, numbers, and true render as attributes, while non-primitives and false are omitted. Declare the properties the element supports and verify behavior against the React version and rendering path used by the host.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Expose events across the boundary

Use CustomEvent when a non-React consumer needs to respond to something the React component does. Specify the event name, the payload in event.detail, and whether it bubbles or crosses a shadow boundary. In the example, profile-select is a lowercase, hyphenated event with both bubbles and composed enabled; choose those options to match the intended consumers rather than copying them automatically.

React hosts can listen to custom-element events using an on-prefixed JSX prop. Event names are case-sensitive, so preserve the exact capitalization and hyphens defined by the element. See React’s custom-element documentation for the host-side behavior.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Handle lifecycle, reconnection, and server rendering

connectedCallback() is the point to initialize rendering, and disconnectedCallback() is the point to unmount the React root. If an element can be removed and later reinserted, ensure that reconnection creates a fresh root and renders its current inputs without creating duplicate mount nodes. Also decide whether the wrapper owns only a dedicated child container or other DOM within the custom element; React takes control of the root container it renders into.

createRoot() is for client rendering. If the integration receives server-rendered React markup that should be reused, React provides hydrateRoot() for hydration instead of replacing that markup. The correct approach depends on how the custom element is delivered and whether its markup is server-rendered; confirm the deployment’s SSR requirements before choosing a root API. See the createRoot reference and React’s hydrateRoot reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Decide whether to use Shadow DOM

Shadow DOM is optional. Rendering into a normal child node keeps the content in the light DOM; using a shadow root can provide DOM and style encapsulation. Choose it only if encapsulation is part of the component’s contract, since it changes how styles and consumers interact with the rendered content. MDN’s Web Components overview describes Shadow DOM as one of the technologies that can be combined with custom elements.

For broad browser compatibility, prefer an autonomous element extending HTMLElement. Customized built-in elements extend an existing native element, but MDN notes that Safari does not plan to support them (MDN: Using custom elements).

Production readiness checklist

  • Define which inputs are HTML attributes and which are JavaScript properties.
  • Handle property assignments made before connection, supported attribute changes, and removal followed by reconnection.
  • Document each emitted event’s exact name, payload shape, and bubbling behavior.
  • Choose light DOM or Shadow DOM based on the required style and DOM boundaries.
  • Use createRoot() for client rendering or hydrateRoot() when reusing server-rendered React markup.
  • Verify the host React version, browsers, bundler setup, and SSR behavior for the deployment.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.