Reputation: 1021
I've just started learning React and was trying to create a chrome extension using it. I am trying to create an extension with a button whose onClick will highlight certain given words on a webpage. I am able to highlight words in content I am introducing to the page but not in the content already present on the page
Here is the code I have come up with -
There is a button on the popup HTML with class highlight-hazardous-words
popup.js (extensions popup):
window.onload = () => {
const $highlightHazardousButton = document.querySelector('.highlight-hazardous-words');
$highlightHazardousButton.onclick = () => {
// Get active tab
chrome.tabs.query({
active: true,
currentWindow: true,
}, (tabs) => {
// Send message to script file
chrome.tabs.sendMessage(
tabs[0].id,
{ injectApp: true },
response => window.close()
);
});
};
};
main.js(main react app content lies here):
import React from 'react';
import ReactDOM from 'react-dom';
import Highlighter from "react-highlight-words"
class HighlightHazardous extends React.Component {
constructor(props) {
super(props);
this.state = {searchWords : this.props.searchWords, textToHighlight : this.props.textToHighlight}
}
render() {
return (
<Highlighter
highlightClassName="highlighted-text"
searchWords = {this.state.searchWords}
autoEscape = {true}
textToHighlight = {document.body.innerText}
/>
)
}
}
// Message Listener function
chrome.runtime.onMessage.addListener((request, sender, response) => {
// If message is injectApp
if(request.injectApp) {
// Inject our app to DOM and send response
injectApp();
response({
startedExtension: true,
});
}
});
function injectApp() {
const newDiv = document.createElement("div");
newDiv.setAttribute("id", "chromeExtensionReactApp");
document.body.appendChild(newDiv);
ReactDOM.render(<HighlightHazardous searchWords={['hazardous', 'alcoholic']}/>, newDiv);
}
Here the newDiv appended has highlighted words with the whole page's body, I want to highlight hazardous or alcoholic present anywhere on any webpage and not in new div, basically, I don't want to inject this new div and change the content of the page already present.
Upvotes: 2
Views: 3212
Reputation: 2974
The only way to access web-page's DOM content is to use Content Scripts
component where Chrome Extensions use content-scripts to mention a JS and CSS file in manifest.json
, that need to be injected into the underlying page.
As stated below:
The problem with our
create-react-app
is that the build step will generate the output JS file in different name each time (if the content changed). So we have no way to know the actual file name of the JS file, hence we can’t mention it in our manifest.json file.
The workaround for this is to eject out of create-react-app
and modify the webpack configuration by hand to create a separate entry point for content script.
Sources:
Upvotes: 3