最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Proper way to inject React Component onto page in Chrome Extension? - Stack Overflow

programmeradmin4浏览0评论

I am making a Chrome Extension and I want to inject HTML into the page DOM using the content scripts. That is easy, but I also want the content script to be a React component and the JS itself does not need to interact with the page JavaScript context, so that makes it simpler. I have a simple way to inject a container element into the DOM that my React code can render to, but I feel like it is very hacky and so I was wondering if there was an official way that React developers could suggest (Google was not particularly useful on this specific matter).

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
  render() {
    return <h1>App was injected.</h1>
  }
};

let container = document.createElement('div');
container.setAttribute("id", "app-wrapper");
document.body.appendChild($el);

ReactDOM.render(
  <App/>, container);

I am making a Chrome Extension and I want to inject HTML into the page DOM using the content scripts. That is easy, but I also want the content script to be a React component and the JS itself does not need to interact with the page JavaScript context, so that makes it simpler. I have a simple way to inject a container element into the DOM that my React code can render to, but I feel like it is very hacky and so I was wondering if there was an official way that React developers could suggest (Google was not particularly useful on this specific matter).

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
  render() {
    return <h1>App was injected.</h1>
  }
};

let container = document.createElement('div');
container.setAttribute("id", "app-wrapper");
document.body.appendChild($el);

ReactDOM.render(
  <App/>, container);
Share Improve this question edited Oct 15, 2018 at 18:45 user3661841 asked Apr 13, 2016 at 12:58 user3661841user3661841 4481 gold badge3 silver badges13 bronze badges 5
  • 2 What's hacky about it? ReactDOM.render requires an element to render to other than document.body, so you create the element via DOM API. Seems pretty straightforward to me. – Pavlo Commented Apr 13, 2016 at 13:02
  • I just wanted to be sure that there was not a more official way of setting up the environment using the React API as opposed to generating the container with straight JS. – user3661841 Commented Apr 13, 2016 at 13:25
  • Hi @user3661841 , is the code you posted your content script? I can't import in the content script, I was wondering where in your app this code lived. – Spothedog1 Commented Jul 26, 2020 at 17:30
  • @Spothedog1 its been a while since I messed with this, but if I am remembering correctly, I used the chrome.tabs.executeScript API in the content script to inject the script onto the page. I am not sure if that is the correct API anymore since they have made some changes to how the extensions work. – user3661841 Commented Jul 29, 2020 at 14:37
  • 1 @user3661841I figured it out thanks for replying. For anyone reading this I followed this blog. – Spothedog1 Commented Jul 29, 2020 at 23:28
Add a comment  | 

3 Answers 3

Reset to default 5

This solution is based on: https://github.com/yosevu/react-content-script .


Inside App.js:

import React from 'react';

function App() {
  return (
    <>
      <h1>Hello World</h1>
    </>
  )
}

export default App;

Inside content.js:

import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App'

const body = document.querySelector('body')
const app = document.createElement('div')

app.id = 'react-root'

if (body) {
  body.prepend(app)
}

const container = document.getElementById('react-root');
const root = createRoot(container);

root.render(<App/>)  // Render react component

Result:

I've found there's broadly two ways to do it. Both involve creating a new element somewhere in the <body> and attaching the ReactDom.render call to it.

  1. Using content scripts - but this can be a headache for React (ejecting create-react-app and managing webpack)
  2. Injecting the code directly from the Background.js script when a tab is active. To do this you can use chrome.tabs.executeScript. There is a short blog on it here: https://dev.to/anobjectisa/build-a-chrome-extension-using-reactjs-38o7

Usually it's split into 2 files, one HTML and one JS. Something like this:

index.html

<head>
  <script src="path/to/bundle.js"></script>
</head>
<body>
  <div id="app-wrapper" />
</body>

App.js

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
  render() {
    return <h1>App was injected.</h1>
  }
};

ReactDOM.render(
  <App/>, document.getElementById("app-wrapper"));

I don't know about an official way, but this is the implementation found in create-react-app and most of tutorials around.

发布评论

评论列表(0)

  1. 暂无评论