The other week, I was building a neat little feature for the poketto.me browser extensions (Chrome, Firefox, and Edge): when you save a web page, the extension should capture not just the URL, but the entire content you’re looking at in that moment.

🤨Why does this matter?

If you’re signed in on a page (say, with your New York Times subscription), poketto.me can capture the full article — just as you, the paying subscriber, see it. Otherwise, poketto.me tries to fetch the article in the background… but it will run straight into the paywall (see TIL #59).

My first instinct was to use a content script: inject JavaScript into the page to grab its content. After some fiddling, I got that to work well enough:

📩 Extension side:

const \[tab\] = await chrome.tabs.query({ active: true, currentWindow: true });

chrome.tabs.sendMessage(tab.id, { text: \'get_page_content\' }, pageContentReceived);

📨 Content script side:

chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {\
  if (msg.text === \'get_page_content\') {\
    const fullHTML = document.documentElement.outerHTML;\
    sendResponse(fullHTML);\
  }\
});

The problem? To inject this script, the extension has to request permission for “any URL” in manifest.json. And if you try to submit that to the Chrome Web Store (or Mozilla), you get a big red warning. That triggers a manual review with an uncertain outcome.

So — back to the drawing board.

Turns out, there’s a simpler solution: no content script needed. You can run JavaScript in the active tab directly:

const executeScript = (tabId, func) =\>\
  new Promise(resolve =\> {\
  chrome.scripting.executeScript({ target: { tabId }, func }, resolve)\
})