diff --git a/web/modules/custom/react_jitsi/.gitignore b/web/modules/custom/react_jitsi/.gitignore
new file mode 100644
index 0000000..3943b66
--- /dev/null
+++ b/web/modules/custom/react_jitsi/.gitignore
@@ -0,0 +1,33 @@
+dist
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# Dependency directories
+node_modules/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# yarn v2
+.yarn/cache
+.yarn/unplugged
+.yarn/build-state.yml
+.pnp.*
diff --git a/web/modules/custom/react_jitsi/js/index.js b/web/modules/custom/react_jitsi/js/index.js
new file mode 100644
index 0000000..665b5f3
--- /dev/null
+++ b/web/modules/custom/react_jitsi/js/index.js
@@ -0,0 +1,16 @@
+import React from "react";
+import ReactDOM from "react-dom";
+
+class Greeting extends React.Component {
+
+ render() {
+ return (
+
+ {this.props.text}
+
+ );
+ }
+
+}
+
+ReactDOM.render(, document.getElementById('page'));
diff --git a/web/modules/custom/react_jitsi/mix-manifest.json b/web/modules/custom/react_jitsi/mix-manifest.json
new file mode 100644
index 0000000..d6b5613
--- /dev/null
+++ b/web/modules/custom/react_jitsi/mix-manifest.json
@@ -0,0 +1,4 @@
+{
+ "/dist/app.js": "/dist/app.js",
+ "/dist/app.js.map": "/dist/app.js.map"
+}
diff --git a/web/modules/custom/react_jitsi/package.json b/web/modules/custom/react_jitsi/package.json
new file mode 100644
index 0000000..88695c6
--- /dev/null
+++ b/web/modules/custom/react_jitsi/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "react-jitsi",
+ "version": "1.0.0",
+ "license": "MIT",
+ "scripts": {
+ "build": "yarn run production",
+ "develop": "cross-env NODE_ENV=development webpack --progress --hide-modules --config=webpack.config.js",
+ "hot": "cross-env NODE_ENV=development webpack-dev-server --inline --hot --config=webpack.config.js",
+ "production": "cross-env NODE_ENV=production webpack --no-progress --hide-modules --config=webpack.config.js",
+ "watch": "yarn run develop --watch"
+ },
+ "dependencies": {
+ "cross-env": "^7.0.2",
+ "laravel-mix": "^5.0.4",
+ "resolve-url-loader": "^3.1.1",
+ "vue-template-compiler": "^2.6.11"
+ },
+ "devDependencies": {
+ "browser-sync": "^2.26.7",
+ "browser-sync-webpack-plugin": "2.2.2",
+ "husky": "^4.2.5",
+ "webpack": "^4.43.0",
+ "webpack-cli": "^3.3.11",
+ "webpack-dev-server": "^3.10.3"
+ },
+ "husky": {
+ "hooks": {
+ "pre-push": "echo -e 'Husky pre-push is not yet setup.\n' "
+ }
+ }
+}
diff --git a/web/modules/custom/react_jitsi/react_jitsi.info.yml b/web/modules/custom/react_jitsi/react_jitsi.info.yml
new file mode 100644
index 0000000..0ce8ce3
--- /dev/null
+++ b/web/modules/custom/react_jitsi/react_jitsi.info.yml
@@ -0,0 +1,5 @@
+name: React Jitsi
+description: Adds a custom page to load up a React app for Jitsi Meets.
+package: Custom
+type: module
+core_version_requirement: ^8.8.0 || ^9.0
diff --git a/web/modules/custom/react_jitsi/react_jitsi.libraries.yml b/web/modules/custom/react_jitsi/react_jitsi.libraries.yml
new file mode 100644
index 0000000..5921f87
--- /dev/null
+++ b/web/modules/custom/react_jitsi/react_jitsi.libraries.yml
@@ -0,0 +1,4 @@
+react_jitsi:
+ version: 1.0
+ js:
+ dist/app.js: { minified: true }
diff --git a/web/modules/custom/react_jitsi/react_jitsi.module b/web/modules/custom/react_jitsi/react_jitsi.module
new file mode 100644
index 0000000..cc35c59
--- /dev/null
+++ b/web/modules/custom/react_jitsi/react_jitsi.module
@@ -0,0 +1,10 @@
+getPath() === '/meet') {
+ $attachments['#attached']['library'][] = 'react_jitsi/react_jitsirou';
+ }
+}
diff --git a/web/modules/custom/react_jitsi/react_jitsi.routing.yml b/web/modules/custom/react_jitsi/react_jitsi.routing.yml
new file mode 100644
index 0000000..9633375
--- /dev/null
+++ b/web/modules/custom/react_jitsi/react_jitsi.routing.yml
@@ -0,0 +1,7 @@
+react_jitsi.controller_react_page:
+ path: 'meet'
+ defaults:
+ _controller: '\Drupal\react_jitsi\Controller\ReactJitsiController::reactPage'
+ _title: 'Meet Remotely'
+ requirements:
+ _permission: 'access content'
diff --git a/web/modules/custom/react_jitsi/src/Controller/ReactJitsiController.php b/web/modules/custom/react_jitsi/src/Controller/ReactJitsiController.php
new file mode 100644
index 0000000..95d7594
--- /dev/null
+++ b/web/modules/custom/react_jitsi/src/Controller/ReactJitsiController.php
@@ -0,0 +1,86 @@
+currentPath = $current_path;
+ $this->currentUser = User::load($currentUser->id());
+ $this->entityTypeManager = $entityTypeManager;
+ $this->formBuilder = $formBuilder;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ return new static(
+ $container->get('path.current'),
+ $container->get('current_user'),
+ $container->get('entity_type.manager'),
+ $container->get('form_builder')
+ );
+ }
+
+ /**
+ * React page.
+ *
+ * @return array
+ * Render array.
+ */
+ public function reactPage() {
+ return [
+ '#type' => 'inline_template',
+ '#template' => '',
+ ];
+ }
+
+}
diff --git a/web/modules/custom/react_jitsi/webpack.config.js b/web/modules/custom/react_jitsi/webpack.config.js
new file mode 100644
index 0000000..8820200
--- /dev/null
+++ b/web/modules/custom/react_jitsi/webpack.config.js
@@ -0,0 +1,13 @@
+const mix = require("laravel-mix/src/index");
+
+const ComponentFactory = require("laravel-mix/src/components/ComponentFactory");
+
+new ComponentFactory().installAll();
+
+require(Mix.paths.mix());
+
+Mix.dispatch("init", Mix);
+
+const WebpackConfig = require("laravel-mix/src/builder/WebpackConfig");
+
+module.exports = new WebpackConfig().build();
diff --git a/web/modules/custom/react_jitsi/webpack.mix.js b/web/modules/custom/react_jitsi/webpack.mix.js
new file mode 100644
index 0000000..6cb854a
--- /dev/null
+++ b/web/modules/custom/react_jitsi/webpack.mix.js
@@ -0,0 +1,15 @@
+const mix = require('laravel-mix');
+const postCssVariables = require('postcss-css-variables');
+
+mix.disableNotifications()
+ .js('js/app.js', 'dist')
+ .sourceMaps()
+ .webpackConfig({
+ devtool: "source-map",
+ externals: {
+ jquery: "jQuery"
+ }
+ })
+ .browserSync({
+ proxy: 'localhost:8888'
+ });