Build Web Component with React and use it in an Angular app

Talha Munir
3 min readMay 24, 2021

--

In this article, I use react-to-webcomponent to package a React app as a web-component and use it as a micro frontend in an Angular app.

Here’s what we create in this article:

Angular app using web-component to show list

The react application is very basic to show a list of string by using Material UI. To show how to pass data from another app, the list is provided as props from an angular app. While angular app is sending data and provide search functionality and also reusing web-component to show the list.

It’s not possible to show all the code here but if you want to follow along use the code here: Example code of React and Example code of Angular .

Steps to convert React component to custom element

  1. After creating a react app, add react-to-webcomponent library:
yarn add react-to-webcomponent

2. Import react-to-webcomponent into index.js and use the reactToWebComponent function exported from the module to create a web-component and then register that component. The code is shown below:

import reactToWebComponent from "react-to-webcomponent";const app = reactToWebComponent(App, React, ReactDOM);
customElements.define("app-webcomponent", app);

3. Build the app by running yarn build and then you can use new html tag <app-webcomponent></app-webcomponent> in another website by adding a script tag that points to the file created by the build script.

Host the build files locally

You can follow the following steps to server the static files for test purposes.

1. I have used the following script to merge the build files into one single file with name main.js.

#!/usr/bin/env nodeconst { readFile } = require("fs").promises;
const concat = require("concat");
(async function build() {
try {
const assetManifestPath = "./build/asset-manifest.json";
const { entrypoints } = JSON.parse(
await readFile(assetManifestPath, "utf8")
);
const filePaths = entrypoints
.filter((path) => /\.js$/.test(path))
.map((path) => `./build/${path}`);
const outFile = "./build/main.js";
await concat(filePaths, outFile);
console.log(
`Concatenated the following files into ${outFile}\n\n${filePaths.join("\n")}`
);
} catch (error) {
console.error(error);
}
})();

2. You need to update your build script inside package.json file.

"build": "react-scripts build && ./concatBuiltJs.js"

3. Install http-server if it is not already installed on you machine.

yarn global add http-server

4. Run the following command from your project to serve build files

http-server -p 4202 build

Use web-component in an Angular app

  1. Create a basic angular app using ng new angular-app
  2. Add local-proxy.config.json file to target build files. Remember to keep the same port in config file as you did while running http-server
{
"/micro-frontend/main.js": {
"target": "http://localhost:4202",
"secure": false,
"logLevel": "debug",
"changeOrigin": true,
"pathRewrite": {"^/micro-frontend" : ""}
}
}

3. Add script tag inside index.html file in your angular app to point to your build file.

<script type="text/javascript" src="/micro-frontend/main.js"></script>

4. Now you can use the new html tag of your web-component and provide the correct input/ props.

<app-webcomponent [data]="data"></app-webcomponent>private readonly data = [
"Fantastic Plastic Shoes",
"Fantastic Steel Car",
"Licensed Steel Gloves",
"Rustic Wooden Hat",
"Handmade Granite Chicken",
"Generic Rubber Sausages",
"Refined Granite Shoes",
"Rustic Wooden Computer",
"Licensed Rubber Chair",
"Refined Granite Car"
];

Success 🚀 We have achieved what we wanted! 🎉

Please let me know your feedback via 👏 or 📝

--

--