I’m developing a Chrome extension that needs to send custom events triggered on the YouTube watch page (e.g., when a video ends) to a React/Next.js web application running on a different domain (localhost during development). The event should trigger specific actions within the web app.
My content script is successfully injected into the YouTube watch page, and I’m able to detect the events I need. However, I’m having a hard time sending these events back to my web app.
I’ve tried using window.postMessage
directly from the content script like this:
window.postMessage({ action: 'videoEnded', videoId }, '*');
and then trying to capture it on my React component with:
useEffect(() => {
const messageListener = (event) => {
if (event.origin === 'https://www.youtube.com') {
if (event.data.action === 'videoEnded') {
console.log('Video ended in YouTube!');
}
}
};
window.addEventListener('message', messageListener);
return () => {
window.removeEventListener('message', messageListener);
};
}, []);
but nothing it’s happening. I’m guessing window object in the content script and the window object in my React app are isolated or there’s some sort of cross-origin security policy.
I’ve also tried using the Chrome Extension Messaging API (chrome.runtime.sendMessage and chrome.tabs.sendMessage), but that only works in the context of the extension and there’s no way to use those APIs within a standard React application.
How can I achieve this cross-origin communication between a Chrome extension content script running on the YouTube watch page and a React/Next.js web app?