I build react widget by this tutorial https://tekinico.medium.com/build-a-react-embeddable-widget-c46b7f7999d8 I squashed all the files by bundler tool called parcel.
after I have the two files (js and css), I'm trying to host this widget in other react project so I opened react project and in index.html I added the js and css files
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<link href="https://tekinico.com/demo/react-widget/index.css" rel="stylesheet" />
<script src="https://tekinico.com/demo/react-widget/index.js"></script>
<!-- <link href="https://firebasestorage.googleapis.com/v0/b/fir-firestore-9702f.appspot.com/o/index.css?alt=media&token=62a7013c-185c-4f9b-ae56-fd2572c769ef" rel="stylesheet"/>
<script src="https://firebasestorage.googleapis.com/v0/b/fir-firestore-9702f.appspot.com/o/index.js?alt=media&token=55069135-ea09-480c-a297-354f009c497b"></script> -->
</html>
in app.js I added the div with the class "nicoraynaud-finance-widget" for the widget
import './App.css';
function App() {
return (
<div className="App">
<div data-symbol="GME" className="nicoraynaud-finance-widget" style={{'width': '250px', 'margin': 'auto', 'marginTop': '20px'}}></div>
</div>
);
}
export default App;
but in the browser I don't see nothing. it loaded the css and js files, I get the error of devtools, in network it shows it get loaded the script and css correctly but I see blank window.
Your widget is not showing in your react app because the widget script is loaded and run before your react app has been injected into the DOM. So your widget is trying to query for and inject html into the 'finance-widget' div, however, that div does not yet exist in the DOM (on the page).
You need to split up the loading of the script and the initialization of the widget React app in order to ensure your main App component has been mounted in the page prior to the initialization of the widget.
Go to your widget app, in index.js
:
You can change:
// Inject our React App into each class
widgetDivs.forEach(div => {
ReactDOM.render(
<React.StrictMode>
<App symbol={div.dataset.symbol}/>
</React.StrictMode>,
div
);
});
to:
// wrap the react app injection in an init function
window.initFinanceWidget = function() {
// important to query for 'nicoraynaud-finance-widget' class when we are ready to initialize the widget
const widgetDivs = document.querySelectorAll('.nicoraynaud-finance-widget');
// Inject our React App into each class
widgetDivs.forEach(div => {
ReactDOM.render(
<React.StrictMode>
<App symbol={div.dataset.symbol}/>
</React.StrictMode>,
div
);
});
}
Then, back in your main project, init the widget in your App component (app.js
) after the component has mounted, using a useEffect hook
import { useEffect } from 'react';
import './App.css';
function App() {
useEffect(() => {
window.initFinanceWidget();
}, [])
return (
<div className="App">
<div data-symbol="GME" className="nicoraynaud-finance-widget" style={{'width': '250px', 'margin': 'auto', 'marginTop': '20px'}}></div>
</div>
);
}
export default App;