{"id":13575759,"url":"https://github.com/LukasBombach/react-web-component","last_synced_at":"2025-04-04T23:30:38.288Z","repository":{"id":44745852,"uuid":"100247161","full_name":"LukasBombach/react-web-component","owner":"LukasBombach","description":"Create Web Components with React","archived":false,"fork":false,"pushed_at":"2022-08-05T11:31:06.000Z","size":117,"stargazers_count":286,"open_issues_count":27,"forks_count":40,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-03-31T17:21:17.557Z","etag":null,"topics":["react","shadow-dom","web-component"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LukasBombach.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-14T08:50:06.000Z","updated_at":"2025-02-27T11:56:18.000Z","dependencies_parsed_at":"2022-08-12T11:21:45.397Z","dependency_job_id":null,"html_url":"https://github.com/LukasBombach/react-web-component","commit_stats":null,"previous_names":["weltn24/react-web-component"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LukasBombach%2Freact-web-component","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LukasBombach%2Freact-web-component/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LukasBombach%2Freact-web-component/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LukasBombach%2Freact-web-component/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LukasBombach","download_url":"https://codeload.github.com/LukasBombach/react-web-component/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247266474,"owners_count":20910831,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react","shadow-dom","web-component"],"created_at":"2024-08-01T15:01:03.964Z","updated_at":"2025-04-04T23:30:37.980Z","avatar_url":"https://github.com/LukasBombach.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"React Web Component Logo\" src=\"https://raw.githubusercontent.com/WeltN24/react-web-component/master/docs/images/react-web-component-logo.png\"\u003e\n\u003c/p\u003e\n\n# React Web Component\n\nCreate Web Components with React\n\n* [Installation](#installation)\n* [Basic Usage](#basic-usage)\n* [Lifecycle methods](#lifecycle-methods)\n* [Adding CSS to your web component using `react-web-component-style-loader`](#adding-css-to-your-web-component-using-react-web-component-style-loader)\n* [Adding CSS to your web component imperatively](#adding-css-to-your-web-component-imperatively)\n* [Usage with `react-router`](#usage-with-react-router)\n* [Issues](#issues)\n* [Maintainers](#maintainers)\n\n## Installation\n\nReact Web Component is available as the `react-web-component` package on npm.\n\n```\nyarn add react-web-component\n```\n\n## Basic Usage\n\nTo create a web component with `react-web-component`, simply pass a React component as the first parameter to `ReactWebComponent.create` and the name of the web component you would like to create as the second parameter.\n\n```javascript\nimport React from 'react';\nimport ReactWebComponent from 'react-web-component';\n\nclass App extends React.Component {\n  render() {\n    return \u003cdiv\u003eHello World!\u003c/div\u003e;\n  }\n}\n\nReactWebComponent.create(\u003cApp /\u003e, 'my-component');\n```\nThen in your HTML simply use your web component, in this case named `my-component`.\n\n```html\n\u003cmy-component\u003e\u003c/my-component\u003e\n```\n\nBy default the `shadowRoot` is enabled. This allows for styles isolation and prevents component styles from \n*bleeding out* to other parts of the application. It also prevents outer styles from affecting the web component you are creating. \n\nIn case that you want your component to inherit styles from the parent you can opt-out of the shadowRoot.\nTo do that you can pass an **optional** parameter to the `create` method:\n```js\nReactWebComponent.create(\u003cApp /\u003e, 'my-component', true);\n```\n\n\nIt is also possible to create multiple web components in a single project and pass on props:\n\n```javascript\nimport React from 'react';\nimport ReactWebComponent from 'react-web-component';\n\nclass MyComponent extends React.Component {\n  render() {\n    return \u003cdiv\u003eHello World!\u003c/div\u003e;\n  }\n}\n\nclass AnotherComponent extends React.Component {\n  render() {\n    return \u003cdiv\u003eHello {this.props.name}!\u003c/div\u003e;\n  }\n}\n\nReactWebComponent.create(\u003cMyComponent /\u003e, 'my-component');\nReactWebComponent.create(\u003cAnotherComponent name=\"Mars\" /\u003e, 'another-component');\n```\n\nNote that `react-web-component` does not limit you in the complexity of your React component. You can pass an entire single page application in your web component if you need to.\n\n## Lifecycle methods\n\nWeb Components have their own lifecycle methods so we proxy them to your React Component. The following table shows which Web Component lifecycle method will trigger which lifecycle method on your React Component:\n\n| Web Component            | React Component              |\n| -----------------------  | ---------------------------- |\n| attachedCallback         | webComponentAttached         |\n| connectedCallback        | webComponentConnected        |\n| disconnectedCallback     | webComponentDisconnected     |\n| attributeChangedCallback | webComponentAttributeChanged |\n| adoptedCallback          | webComponentAdopted          |\n\n**Example:**\n\n```javascript\nimport React from 'react';\nimport ReactWebComponent from 'react-web-component';\n\nclass App extends React.Component {\n\n  componentDidMount() {\n    // Regular React lifecycle method\n  }\n\n  webComponentAttached() {\n    // will be called when the Web Component has been attached\n  }\n\n  render() {\n    return \u003cdiv\u003eHello World!\u003c/div\u003e;\n  }\n}\n\nReactWebComponent.create(\u003cApp /\u003e, 'my-component');\n```\n\nParameters passed to the web component methods will also be proxied to the react component.\n\n## Adding CSS to your web component using `react-web-component-style-loader`\n\nThe challenge of adding CSS to your web component is that (as compared to a regular React component) you cannot simply put your CSS anywhere in your site, you need to inject it into the shadow dom of your web component, while at the same time you'll still want to use state of the art tooling (i.e. webpack) and create component based (S)CSS files.\n\nWe've got you covered. You can use the [react-web-component-style-loader](https://github.com/WeltN24/react-web-component-style-loader) webpack loader module that in combination with `react-web-component` will inject the css imported anywhere in your project into your web component. Here is a quick example:\n\n**App.js**\n```javascript\nimport React from 'react';\nimport './app.css';\n\nexport default class App extends React.Component {\n  render() {\n    return \u003cdiv\u003eHello World!\u003c/div\u003e;\n  }\n}\n```\n**index.js**\n```javascript\nimport React from 'react';\nimport ReactWebComponent from 'react-web-component';\nimport App from './App';\nimport './index.css';\n\nReactWebComponent.create(\u003cApp /\u003e, 'my-component');\n```\n\nUsing the `react-web-component-style-loader` both the CSS from `app.css` as well as `index.css` will end up in your web component. Read more about it in the [react-web-component-style-loader repository](https://github.com/WeltN24/react-web-component-style-loader).\n\n## Adding CSS to your web component imperatively\n\n* *todo: allow `ReactWebComponent.create(\u003cApp /\u003e, 'my-component', { style: '' });`*\n* *todo: allow `ReactWebComponent.create(\u003cApp /\u003e, 'my-component', { cssFile: '' });`*\n\n## Usage with `react-router`\n\n`react-web-component` works with `react-router` with one restriction: Since web components live within a host website you should now modify the URL of the website when the web component does internal routing. Luckily `react-router` comes with an _in memory_ router that does not alter the URL and keeps the state of the router internally.\n\n```javascript\nimport React from 'react';\nimport {\n  MemoryRouter as Router,\n  Route,\n  Link,\n  withRouter\n} from 'react-router-dom';\nimport ReactWebComponent from 'react-web-component';\nimport { Home, About, Topics } from './components';\n\nconst App = withRouter(({ history}) =\u003e (\n  \u003cdiv\u003e\n    \u003cul\u003e\n      \u003cli\u003e\u003cLink to=\"/\"\u003eHome\u003c/Link\u003e\u003c/li\u003e\n      \u003cli\u003e\u003cLink to=\"/about\"\u003eAbout\u003c/Link\u003e\u003c/li\u003e\n      \u003cli\u003e\u003cLink to=\"/topics\"\u003eTopics\u003c/Link\u003e\u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cRoute exact path=\"/\" component={Home}/\u003e\n    \u003cRoute path=\"/about\" component={About}/\u003e\n    \u003cRoute path=\"/topics\" component={Topics}/\u003e\n  \u003c/div\u003e\n))\n\nconst RoutedApp = () =\u003e (\n  \u003cRouter initialEntries={[ '/' ]}\u003e\n    \u003cApp /\u003e\n  \u003c/Router\u003e\n);\n\nReactWebComponent.create(\u003cRoutedApp /\u003e, 'my-routed-component');\n```\n\n## Issues\n\n### If you encounter that some events won't be triggered\n\nIf you encounter that an event that you rely on will not get triggered this is probably our fault (or Facebook's to be precise). React does not catch events inside shadow dom. A bug ticket has been filed for this at [react#10422](https://github.com/facebook/react/issues/10422). For now, we have created a workaround for this [in the shape of another npm package](https://github.com/WeltN24/react-shadow-dom-retarget-events) that this library depends on. In this library we listen for events on the DOM level and pass them on to React. If an event does not get triggered it probably means we have forgotten it in the list of events that we subscribe to. This is very inconvenient but not a problem. We can simply add it. Open an issue or a PR at [WeltN24/react-shadow-dom-retarget-events](https://github.com/WeltN24/react-shadow-dom-retarget-events) and we will gladly add the event.\n\n## Maintainers\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\"\u003e\n        \u003ca href=\"https://github.com/LukasBombach\"\u003e\n          \u003cimg width=\"150\" height=\"150\" src=\"https://github.com/LukasBombach.png?v=3\u0026s=150\"\u003e\n          \u003c/br\u003e\n          Lukas Bombach\n        \u003c/a\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003ctbody\u003e\n\u003c/table\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLukasBombach%2Freact-web-component","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLukasBombach%2Freact-web-component","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLukasBombach%2Freact-web-component/lists"}