I am trying to create an embeddable react modal widget that encapsulates login logic already written within the application. The target app may or may not be a react application, given that this widget will be embedded on numerous different applications. Is this possible? Currently I have a React modal widget that opens with the login logic inside, but not in the target application where this will be embedded.
I am using webpack and babel to bundle the appropriate files. Given that this application contains a lot of login logic and is being used in a production env, I've tried to have two separate entries with Webpack (1 for the widget, and 1 for the application code).
For the target app where the widget is going to be embedded, I have tried updating the public/index.html to include the bundled css, and widget js files, but am unable to call any functions in my widget.bundle.js within a script tag.
Hopefully someone can point me in the right direction.
Widget code in App 1 (LoginModalWidget.js)
import React, { useState } from "react";
import "./modal.css";
import Modal from "react-modal";
import { FormClose } from "grommet-icons";
import App from "../../App";
const LoginModalWidget = () => {
const [isOpen, setIsOpen] = useState(true);
function toggleModal() {
setIsOpen(!isOpen);
}
return (
<Modal
isOpen={isOpen}
onRequestClose={toggleModal}
className="login-modal"
overlayClassName="modal-overlay"
closeTimeoutMS={500}
>
<div className="exit-modal-icon">
<FormClose size="medium" onClick={toggleModal}/>
</div>
<div className="modal-form">
<App />
</div>
</Modal>
);
}
export default LoginModalWidget;
Widget.js to render the widget
import React from 'react';
import ReactDOM from 'react-dom';
import LoginModalWidget from './components/login-modal-widget/LoginModalWidget';
function renderWidget() {
ReactDOM.render(
<LoginModalWidget/>,
document.getElementById('widget-container')
);
}
export default {
renderWidget: renderWidget
};
webpack.config.js
const path = require('path');
module.exports = {
mode: 'development', // or 'production'
entry: {
app: './src/index.js',
widget: './src/widget.js', // your widget's entry file
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
},
},
},
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
},
},
],
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
],
},
],
},
};
Target app public index.html
<html lang="en">
<head>
<meta charset="utf-8" />
<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"
/>
<title>APPPPPP</title>
<link rel="stylesheet" href="/build/static/css/main.3e38205f.chunk.css" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="widget-container"></div>
<script src="https://68aad57e.hpe-test.pages.dev/widget.bundle.js" name="widget"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<script>
<!--how can I call the renderWidget function from the bundled widget.bundle.js file imported above?---!>
</script>
</body>
</html>