I am trying to build a react chrome extension. I started off with the simple project found here. In its structure, the popup is contained in Modal.js and I would like to include an image in it which is contained in the project. However, to access that I must use chrome.runtime.getURL("image_file.png")
, which I cannot access in Modal.js, but only in content.js. How should I get the image properly to Modal.js?
This is all activated when the browser action button is pressed, which calls this function within content.js:
function main() {
const extensionOrigin = 'chrome-extension://' + chrome.runtime.id
if (!location.ancestorOrigins.contains(extensionOrigin)) {
fetch(chrome.runtime.getURL('index.html'))
.then((response) => response.text())
.then((html) => {
const styleStashHTML = html.replace(
/\/static\//g,
`${extensionOrigin}/static/`
)
$(styleStashHTML).appendTo('body')
})
.catch((error) => {
console.warn(error)
})
}
}
The content of index.html
is:
<div id="modal-window"></div>
but when the html is returned from the fetch it has expanded in the build to:
<div id="modal-window"></div><script src="/static/js/runtime-main.0d1674f1.js"></script><script src="/static/js/2.021a85b4.chunk.js"></script><script src="/static/js/main.d80831e3.chunk.js"></script>
It is unclear to me how index.js is getting called but it is, which finds the div in index.html and replaces it with the modal object as follows:
import React from 'react'
import ReactDOM from 'react-dom'
import Modal from './Components/Modal'
ReactDOM.render(<Modal />, document.getElementById('modal-window'))
My current implementation of modal.js is as follows. Obviously the img src won't work as it is right now (needing to use chrome.runtime.getURL):
import React from 'react'
const Modal = () => {
return <img src="icon48.png" alt="icon48"></img>
}
export default Modal
How would I actually be able to get the image src from chrome.runtime.getURL?
Figured this out. I don't know if this is the best solution, but it is working for me.
Since I need to access chrome.runtime.getURL
I need to do that from the content script. But I need the value of that in my component which doesn't have access to the chrome api. So I message between them through window events. Here is some example code:
ExampleComponent.js
import React, { Component } from 'react'
let imgSrc = 'file.png'
// Note that this listener is outside the Component
window.addEventListener('ToComponent', (msg) => {
imgSrc = msg.detail
})
class ExampleComponent extends Component {
constructor(props) {
super(props)
// Note that this is occurring inside the Component constructor
var event = new CustomEvent('FromComponent')
window.dispatchEvent(event)
this.state = {
imgSrc: imgSrc,
// etc.
}
}
render() {
return (
<img src={this.state.imgSrc} alt=""></img>
)
}
}
content.js:
window.addEventListener('FromComponent', () => {
const imgSrc = chrome.runtime.getURL('file.png')
// Send response
var event = new CustomEvent('ToComponent', { detail: imgSrc })
window.dispatchEvent(event)
})