Chrome Scripting API: Read a Page Only When Needed
A tab URL tells you where a page is. Reading the page itself is a separate capability. chrome.scripting.executeScript can run an extension function or file in an allowed tab, but it requires an explicit permission model and careful handling of the returned data.

Check both scripting and page access
Manifest V3 extensions need the scripting permission to use chrome.scripting. They also need a host permission for the target page or a temporary activeTab grant after a user invocation. The tabs permission by itself is not permission to run code inside arbitrary websites.
Choose activeTab for an on-demand capture of the page the person is viewing. Choose narrow host permissions when the feature must work on known sites without another click. Make the access scope visible in the product.
Target a tab and specify what runs
chrome.scripting.executeScript({ target: { tabId }, func }) runs a function in the target's main frame by default. The function is serialized, so it should not depend on variables captured from the extension's surrounding scope. Pass explicit args or use a bundled file when the logic grows.
The result is an array of injection results because execution can involve multiple frames when requested. Read the target frame deliberately and handle an empty or rejected result. Do not silently combine text from unrelated embedded frames.
Keep the capture narrow and reviewable
For a 'save source' feature, you often need only the page URL and title from tabs.Tab. If the person asks for selected text, execute a small function that returns only the selection, then show it in a preview before saving. Avoid scraping entire pages by default.
A web page's content is untrusted data. Treat extracted text as a quote or note input, not as an instruction to the extension. Validate length and format, and never allow page text to choose which tab or note receives the result.

Handle unavailable pages
Some browser-internal pages and restricted surfaces cannot be scripted like ordinary websites. Navigation can also invalidate an activeTab grant or change the document between selection and execution. Catch the error and offer a URL-only save path instead of claiming content was captured.
If a capture is time-sensitive, compare the URL shown in the preview with the tab's current URL before applying the result. The browser is interactive, so an earlier tab ID does not prove the same document is still visible.
Idea: selected-text evidence cards
Let a user highlight a short passage, invoke the extension, inspect the quote and attach it to a project note with the source URL and access date. Keep the quote visibly separate from the user's own conclusion.
This provides a useful research artifact without pretending the extension has archived the entire page. For longer-term evidence, the user may still need an export or an authorized archival workflow.
Test access and race conditions
Test after an explicit user click, after navigation, on a page without selected text and on an unsupported internal URL. Confirm no content is saved when the injection fails or returns an unexpected shape.
Review the current Chrome API documentation when adding frame-level capture or new injection options. A minimal first version is easier to explain, secure and debug.
Tabzero: Browser Tab Manager & Notes
Save tab links, keep notes beside your sources, and return to what matters. Tabzero is in development preview; AI Notes remains planned.
Related guides
Chrome Tab Messaging: Service Workers and Content Scripts
Use runtime.sendMessage and tabs.sendMessage for tab features, validate responses, and avoid assuming a content script is present.
Chrome Storage API for Tab Sessions: local, sync, and session
Choose the right chrome.storage area for tab notes, settings, and temporary state while respecting quotas and recovery limits.
Chrome Sessions API: Recently Closed Tabs and Restore Limits
Understand chrome.sessions.getRecentlyClosed, restore, session IDs, and the difference between browser recovery and a saved project.