I'm currently learning how to develop chrome extension using React. However, i'm stuck with an issue where react re-renders like 3 times even with a very basic component.
As a result, the content script creates iframes 3 times nested on top of each other -- and one thing i've noticed is querying iframe always returns null on every re-render.
Here's the component that will act as a content script that will be injected inside a iframe.
import { render } from 'react-dom';
interface Props {}
const Sidebar: FC<Props> = () => {
return <div>some sidebar</div>;
};
// render first on the entry point
const app = document.getElementById('app');
if (app) {
render(
<StrictMode>
<Sidebar />
</StrictMode>,
document.getElementById('app')
);
}
console.log('check');
const id = 'extensionWrapper';
const iframe = document.getElementById(id);
if (!iframe) {
const iframe = document.createElement('iframe');
// get the index.html from chrome extension directory
const content = chrome.extension.getURL('index.html');
console.log({ content });
iframe.src = content;
iframe.id = id;
document.body.appendChild(iframe);
}
Here's the webpack.config.js
const { resolve } = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const tsRule = {
test: /\.tsx?$/,
exclude: /node_modules/,
use: 'ts-loader',
};
const plugins = [
new HTMLWebpackPlugin({
template: 'src/index.html',
filename: 'index.html',
chunks: ['contentScript'],
inject: 'body',
}),
new CopyWebpackPlugin({
patterns: [
{
from: 'public',
// to is relative to output folder set in output.path
to: '.',
},
],
}),
new CleanWebpackPlugin(),
];
module.exports = {
mode: 'development',
devtool: 'cheap-module-source-map',
entry: {
// popup: './src/popup-page/popup.tsx',
contentScript: './src/content-scripts/content-script.tsx',
},
output: {
filename: '[name].js',
path: resolve(__dirname, 'dist'),
},
module: {
rules: [tsRule],
},
plugins,
};
manifest.json
{
"short_name": "react chrome",
"name": "react chrome extension",
"version": "1.0",
"manifest_version": 2,
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["contentScript.js"]
}
],
"web_accessible_resources": ["*.html"]
}