Jens Jansson

How to use Web Components in React

This tutorial teaches you how to use and interact with web components in React. We’ll build a small UI that adds people to a data grid.

The completed app: A form with two text fields for name and an add button for adding people to a data grid.

Most Web Components, like the Vaadin component set, are distributed as ES modules. To use them efficiently, you need to have a project that handles them, like the one that is created with Create React App

If you already have an existing project that handles ES modules, feel free to skip directly to Step 1.

Step 0: Creating a project with Create React App

You’ll need to have Node 8.10.0 or later installed on your machine. Create a new project by running:

$ npx create-react-app webcomponents
$ cd webcomponents/
$ npm start

This creates the application and launches it. The start script opens up a browser automatically, pointing at http://localhost:3000/ where your app is now running.

Step 1: Install the polyfill

To start using Web Components in React, we need to have a polyfill installed for Web Component support in all browsers. We use the webcomponentsjs polyfill. We also make use of vendor-copy to make the polyfill available on runtime. Let’s start by installing them.

$ npm install --save @webcomponents/webcomponentsjs vendor-copy

Open package.json to enable vendor-copy. To the scripts block, add a postinstall which runs vendor-copy after every time npm install is invoked.

"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject",
  "postinstall": "vendor-copy" (1)
  1. Add this row. Remember the comma on the previous row.

Next, at the end of the same file, give instructions to vendor-copy on what it should copy over when the install is run. We need webcomponents-bundle.js and custom-elements-es5-adapter.js.

"vendorCopy": [
    "from": "node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js",
    "to": "public/vendor/custom-elements-es5-adapter.js"
    "from": "node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js",
    "to": "public/vendor/webcomponents-bundle.js"

Now when you run npm install within the root of the project, it will also trigger the postinstall and copy the polyfill.

Lastly, we have to use the polyfills in runtime by adding them to our index.html. Add the following lines to the end of <body>.

<script src="%PUBLIC_URL%/vendor/webcomponents-bundle.js"></script>
<script>if (!window.customElements) { document.write("<!--"); }</script>
<script src="%PUBLIC_URL%/vendor/custom-elements-es5-adapter.js"></script>

Step 2: Add the web components to your UI

Now we have the support for the web components in place. Let’s continue by installing and adding some.

Install the components

We will start off by installing the components. In this case, we install vaadin-text-field, vaadin-button, and vaadin-grid from the Vaadin component set.

$ npm install --save @vaadin/vaadin-text-field @vaadin/vaadin-button @vaadin/vaadin-grid

Once the install finishes, import the components in App.js to make them available to your browser.

import '@vaadin/vaadin-button';
import '@vaadin/vaadin-grid';
import '@vaadin/vaadin-text-field';

Use Web Components to build the UI

You can now use the Web Components like any other HTML tag. Replace the contents of the render() method in App.js with the following:

render() {
  return (
    <div className="App">
        <div className="form">
          <vaadin-text-field label="First Name" ref="firstName" />
          <vaadin-text-field label="Last Name" ref="lastName" />
          <vaadin-button ref="addButton"> Add </vaadin-button>
        <vaadin-grid ref="grid">
          <vaadin-grid-column path="firstName" header="First name" /> (1)
          <vaadin-grid-column path="lastName" header="Last name" />
  1. The grid uses an array of objects as its data source. The path attribute defines what property of that object should be shown in the column.

Notice that we added ref attributes for all components. This enables us to reference the components from JavaScript in the next step.

Listen for events and update properties

Now that we have all the UI building blocks in place, the next step is to add some functionality.

Start by adding a componentDidMount() function to App.js. It will be run after the templated has been loaded. A fair amount is going on in this function, so let’s look at what’s going on step by step:

componentDidMount() {
  let people = []; (1)
  this.refs.addButton.addEventListener('click', e => { (2)
    people = [ (3)
        firstName: this.refs.firstName.value,
        lastName: this.refs.lastName.value
    this.refs.grid.items = people; (4)
    this.refs.firstName.value = ''; (5)
    this.refs.lastName.value = '';
  1. Define an array to hold the people that are added.

  2. Get references to the components with this.refs. Add a click listener on the button for adding people.

  3. Create a new array with all previous people and a newly created person. The name values can be retrieved from the value property on the components.

  4. Set the new people array as the items property on the grid to display the updated data.

  5. Clear the input fields.

Finally, update the styles in App.css to the following:

.App {
  padding: 4px;
.App .form * {
  margin-right: 4px;

Run the application, and you should now be able to add new entries to the grid.

Summary and next steps

Web Components behave like any other HTML element once you have imported them. You can set and read attributes and properties for data, and listen to events to add interactivity.

Web Components are designed to be framework independent. You can use them together with a framework or templating library to cut down on the boilerplate of manually querying elements and setting their values. See any of our other guides on using Web Components in popular frameworks for further information.

You can read more about web component framework compatibility on

Vaadin is an open-source framework offering the fastest way to build web apps on Java backends

Comments (8)

Jens Jansson
3 years ago Apr 26, 2019 10:45am
Juuso Haapanen
3 years ago Apr 26, 2019 11:07am
Justin Meyer
3 years ago Aug 16, 2019 12:36am