Free tools Windows power users keep installed
One-click scans. No signup required.
Short answer: ordinary webpage JavaScript cannot call Chrome’s extension APIs or silently screenshot another tab. For a user-triggered screenshot, use a Chrome extension and chrome.tabs.captureVisibleTab(). For a user-selected screen or tab, use getDisplayMedia(), which opens a browser sharing prompt. For developer tooling with a privileged Chrome connection, send the DevTools Protocol command Page.captureScreenshot—no Puppeteer required.
First choose where the capture code runs
The right method depends on the privileges your code has and who chooses what gets captured. A script running in a normal webpage does not have access to Chrome’s extension API or an arbitrary browser tab. Chrome provides separate routes for extension code, user-mediated sharing and privileged developer tooling.
| Route | What starts the capture | What it captures | Constraint |
|---|---|---|---|
Chrome extension: chrome.tabs.captureVisibleTab() |
User action in an extension workflow | Visible area of the active tab in a specified window | Requires activeTab or <all_urls>; maximum two calls per second. Chrome Tabs API reference |
getDisplayMedia() |
User approves a browser sharing prompt | The screen, window or tab the user selects | Capture is explicitly user-mediated. Chrome screen-capture guide |
DevTools Protocol: Page.captureScreenshot |
A client connected to Chrome’s DevTools Protocol | Screenshot image data; options include format, quality and clipping | Requires privileged protocol access; not available to ordinary page scripts. Page domain reference |
These are not interchangeable permission shortcuts. Choose an extension when the user wants to capture the tab they are viewing, display capture when the user should choose a source, and DevTools Protocol when your developer tooling controls a browser connection.
Capture the visible tab from a Chrome extension
chrome.tabs.captureVisibleTab() is the direct route for an extension action. Chrome describes it as capturing “the visible area of the currently active tab in the specified window.” It returns a data URL, which extension code can display, store or pass to another extension component.
#1 Best Overall
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Choose the narrowest suitable permission
The method requires either activeTab or <all_urls>. Prefer activeTab when a user explicitly invokes the extension for the current page; use broad host access only when the extension’s actual workflow needs it. Chrome’s reference documents the permission requirement and return type in the Tabs API reference.
Minimal Manifest V3 manifest for an action that captures the visible tab after the user clicks the extension:
{
"manifest_version": 3,
"name": "Visible Tab Capture",
"version": "1.0.0",
"permissions": ["activeTab"],
"action": {},
"background": {
"service_worker": "service-worker.js"
}
}
In service-worker.js, capture the active tab in the current window and open the resulting data URL in a new tab:
chrome.action.onClicked.addListener(async (tab) => {
try {
const imageUrl = await chrome.tabs.captureVisibleTab(tab.windowId, {
format: "png"
});
await chrome.tabs.create({ url: imageUrl });
} catch (error) {
console.error("Could not capture the visible tab:", error);
}
});
This is a small extension pattern, not a webpage snippet: install it as an extension, then click its toolbar action. The official Chrome sample uses the same user-action approach and displays the screenshot in a new tab: Chrome Extensions screenshot sample.
Visible viewport is not the whole page
captureVisibleTab() captures what is currently visible in the active tab. It does not return a full-page screenshot simply because the page is taller than the viewport. If you need the entire document, use a separate scrolling or DevTools-based workflow and account for content that loads as the page scrolls.
Rank #2
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Respect the capture limit
Chrome documents a maximum rate of two captureVisibleTab() calls per second. Do not poll it continuously or use it as a high-frequency video capture loop. Queue or throttle user requests, and show a clear error if a capture fails rather than retrying rapidly. See the current Chrome API reference for the documented limit.
Let the user select a screen, window or tab
If the experience should begin on a webpage and it is acceptable for the user to choose a capture source, getDisplayMedia() presents Chrome’s sharing dialog. The user’s explicit selection is part of the workflow; it is not a silent way to inspect another tab.
For example, a page can request a video stream and stop its tracks when finished:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallasync function chooseCaptureSource() {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: false
});
try {
const video = document.createElement("video");
video.srcObject = stream;
await video.play();
// Use the video stream in the application's capture workflow.
// A single still frame can be drawn to a canvas after the video plays.
} finally {
stream.getTracks().forEach((track) => track.stop());
}
}
button.addEventListener("click", chooseCaptureSource);
Call it from a user action such as a button click, handle cancellation or denial as normal outcomes, and stop the stream when it is no longer needed. Chrome’s screen-capture guide covers the sharing prompt and extension tab-capture workflows. For an extension service-worker workflow, the guide identifies Chrome 116 as the threshold for calling chrome.tabCapture from a service worker and consuming its stream ID in an offscreen document after a user gesture.
Use DevTools Protocol without Puppeteer
“Without Puppeteer” does not mean “without browser access.” Chrome DevTools Protocol provides a screenshot command, but your program still needs a privileged client connection to Chrome’s debugging protocol. The protocol overview explains its role in Chrome DevTools and how commands are sent; the Page domain defines Page.captureScreenshot.
Rank #3
The command returns base64-encoded image data. Its parameters include image format, quality and clipping, with options for capture beyond the viewport. A protocol client sends the command on a connected target’s session; this is not code to paste into an unrelated webpage’s console or a public website script.
{
"id": 1,
"method": "Page.captureScreenshot",
"params": {
"format": "png",
"captureBeyondViewport": true
}
}
The example is the protocol command message, not a complete connection client: establishing and authorizing the DevTools Protocol connection depends on how Chrome was launched and how your tooling obtains that connection. The protocol reference is versioned as “tot” and may evolve, so check the current Page method documentation for supported parameters in your target Chrome setup. If you do not control or cannot access that privileged connection, choose the extension or sharing-prompt route instead.
Recommended Free Tools
Which route fits your use case?
- Screenshot the tab the user is viewing from an extension button: use
captureVisibleTab()withactiveTabfor a user-invoked workflow. - Let the user decide which display source to share: use
getDisplayMedia()and design for the prompt, approval and cancellation states. - Capture in developer tooling or automation that controls Chrome: use
Page.captureScreenshotover a privileged DevTools Protocol connection. - Capture a page on a server without opening a browser-sharing prompt: use a screenshot service API rather than trying to make ordinary page JavaScript access another browser tab.
Troubleshooting common capture failures
The webpage says chrome.tabs is undefined
Cause: the code is running as ordinary webpage JavaScript, not in a Chrome extension context. Fix: move the capture into an extension with the required permission, ask the user to select a source with getDisplayMedia(), or run a privileged DevTools Protocol client.
The extension rejects the capture call
Cause: the extension lacks activeTab or <all_urls>, or the call is made against the wrong window. Fix: verify the manifest permission, invoke the capture after the intended extension action, and pass the active tab’s windowId. Handle rejected promises in the extension UI.
The screenshot contains only part of the document
Cause: captureVisibleTab() captures the visible viewport, not a full document. Fix: use a verified full-page workflow, such as a DevTools Protocol capture with the appropriate beyond-viewport behavior, and test pages with lazy-loaded content.
Rank #4
Capture requests are being throttled
Cause: calls exceed Chrome’s documented maximum of two per second for captureVisibleTab(). Fix: throttle requests, avoid polling, and let pending captures complete before scheduling more.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →The sharing prompt is dismissed or permission is denied
Cause: the user cancelled or did not approve a source. Fix: treat this as an expected outcome, explain how to restart the selection, and do not attempt to bypass the prompt.
The DevTools command cannot be sent
Cause: there is no authorized DevTools Protocol connection or the command is being issued in a normal page context. Fix: establish the privileged connection in your developer tooling and target the intended page session before sending Page.captureScreenshot.
Or skip the browser setup
If your goal is to get an image or PDF of a public webpage rather than capture the tab a user is viewing, ScreenshotNeo provides a screenshot API and MCP server for developers. One GET request takes a URL and returns a screenshot or PDF. The service removes cookie and consent banners, newsletter popups and chat widgets before capture; each of those cleanup steps can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers report the page verdict and billing status. AI agents can use its MCP server tools: take_screenshot, get_page_info and capture_pdf.
For a quick API request, replace the URL with the page you want to capture and use your API key:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. The same endpoint is available from Python and Node.js:
Best Value
- JavaScript Jquery
- Introduces core programming concepts in JavaScript and jQuery
- Uses clear descriptions, inspiring examples, and easy-to-follow diagrams
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo includes 1,000 shots per month on its free plan with no card; paid plans start at $5 for 3,000 shots. Sign up free and get 1,000 screenshots a month with no card.
Frequently Asked Questions
Can ordinary JavaScript on a webpage screenshot another Chrome tab?
No. Use an extension, a user-approved screen-sharing flow or a privileged DevTools Protocol client.
Does captureVisibleTab() capture a full page?
No. It captures the visible area of the active tab.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Can I use DevTools Protocol without Puppeteer?
Yes, if your tooling can establish a privileged Chrome DevTools Protocol connection; Puppeteer is not required for the protocol command itself.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




