ScreenshotNeo

BlogGuides

Can Browserless Capture Screenshots of Localhost and Staging Websites?

Browserless can capture reachable staging sites, but Cloud cannot automatically reach your workstation’s localhost. The browser’s network location determines what it can load.

By the ScreenshotNeo team4 October 20269 min read

Browserless can capture a staging website if the browser process can resolve and reach its URL and the site allows the request. Browserless Cloud runs the browser in Browserless’s hosted environment, so localhost ordinarily refers to that environment—not your workstation. A local development server is not automatically exposed to a hosted browser.

The deciding question is: where does the browser run, and can that machine or container reach the target? A public staging URL is usually the simplest case. A private staging site or local app requires a deliberate network path, suitable routing, and any needed authentication.

1. Understand what localhost means

localhost is relative to the machine or container making the connection. When a browser running in Browserless Cloud navigates to http://localhost:3000, it tries to connect to port 3000 in the Browserless execution environment. It does not connect to port 3000 on the computer that sent the API request.

Sending a URL to a screenshot API does not tunnel the caller’s network connection to that URL. The browser fetches the page from its own execution environment. Browserless documents a hosted Cloud API as well as self-hosted deployment options; the execution location determines what is reachable. See the [Browserless API overview](https://docs.browserless.io/open-api/overview) and [Docker deployment guide](https://docs.browserless.io/enterprise/open-source).

2. Choose the right setup for your target

Target What to expect What to check
Public staging URL with Browserless Cloud Can work if the hosted browser can load the URL. DNS resolution, TLS certificate, access controls, and whether the page permits the request.
Workstation localhost with Browserless Cloud Does not automatically reach your workstation. Run browser execution somewhere with a route to your app, or provide an intentional, secured reachable endpoint.
Private staging with self-hosted Browserless Can work when the deployed browser has a route to the target. Network placement, DNS, firewall rules, Docker networking, URL restrictions, and app authentication.
Local app and self-hosted Browserless in Docker Container networking determines reachability. Which container owns the address, whether containers share a network, and whether the relevant port is exposed and routed.

3. Capture a reachable staging URL with Browserless

The Browserless screenshot REST API accepts a POST request to /screenshot, requires an API token, and can return a screenshot image. The endpoint hostname depends on your Browserless deployment. Set BROWSERLESS_SCREENSHOT_ENDPOINT to the screenshot endpoint shown for your Cloud account or self-hosted instance, including its /screenshot path. The examples pass the token as a query parameter; use the authentication format documented for your deployment. See the [Screenshot API documentation](https://docs.browserless.io/rest-apis/screenshot-api).

cURL

export BROWSERLESS_SCREENSHOT_ENDPOINT='YOUR_BROWSERLESS_SCREENSHOT_ENDPOINT'
export BROWSERLESS_TOKEN='YOUR_BROWSERLESS_TOKEN'

curl --fail-with-body --silent --show-error \
  -X POST "${BROWSERLESS_SCREENSHOT_ENDPOINT}?token=${BROWSERLESS_TOKEN}" \
  -H 'Content-Type: application/json' \
  --data '{"url":"https://staging.example.com"}' \
  --output staging.png

Replace the example staging URL with a page the Browserless browser can reach. The response format and available screenshot controls depend on the endpoint options you choose.

Python

import os
import requests

endpoint = os.environ["BROWSERLESS_SCREENSHOT_ENDPOINT"]
token = os.environ["BROWSERLESS_TOKEN"]

response = requests.post(
    endpoint,
    params={"token": token},
    json={"url": "https://staging.example.com"},
    timeout=90,
)
response.raise_for_status()
with open("staging.png", "wb") as image:
    image.write(response.content)

Node.js

const endpoint = process.env.BROWSERLESS_SCREENSHOT_ENDPOINT;
const token = process.env.BROWSERLESS_TOKEN;
if (!endpoint || !token) throw new Error("Set the Browserless endpoint and token");

const target = new URL(endpoint);
target.searchParams.set("token", token);
const response = await fetch(target, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://staging.example.com" }),
  signal: AbortSignal.timeout(90_000),
});
if (!response.ok) {
  throw new Error(`Browserless returned ${response.status}: ${await response.text()}`);
}
const image = Buffer.from(await response.arrayBuffer());
await import("node:fs/promises").then(({ writeFile }) => writeFile("staging.png", image));

4. Make a private or local target reachable

For Browserless Cloud and workstation localhost

  1. Decide whether the capture must run from your workstation or whether the app can be reached at a protected staging address.
  2. If using Cloud, provide a deliberate network path to the development app or use a reachable staging endpoint. A local MCP client alone does not move Cloud browser execution onto your machine.
  3. Protect any endpoint you expose. Limit access to the intended app and remove temporary exposure when it is no longer needed.
  4. Submit the reachable URL and check the capture response to distinguish a network failure from an application or authentication failure.

For self-hosted Browserless

  1. Place the Browserless deployment where it can route to the app, or configure the required network routes.
  2. For Docker, configure the relevant containers on a shared network when they need to communicate. Remember that localhost inside a container points to that container’s own network namespace.
  3. Check published ports, host routing, DNS, and firewall rules for connections between containers or machines.
  4. Review URL restrictions before navigating to private addresses. Browserless Enterprise Docker documents a built-in blocklist for localhost, private IP addresses, and cloud metadata endpoints. Its configuration reference documents DISABLE_BLOCKLIST; changing this setting alters the protection policy. Assess the network exposure and intended use before changing it. See the [Docker configuration reference](https://docs.browserless.io/enterprise/docker/config).
  5. If the staging app requires login, configure the browser session’s authentication using the integration and account setup appropriate to your application. Authentication behavior varies; verify it against your app rather than assuming a universal credential flow.

5. Use inline HTML when you do not need to load a server

The screenshot API also accepts an html field to render supplied markup instead of navigating to a URL. The documentation warns not to send html and url together. Inline HTML is useful for rendering a self-contained snippet, but it does not establish access to a local development server or a logged-in private staging application. Refer to the [API documentation](https://docs.browserless.io/rest-apis/screenshot-api) for the current request and screenshot options.

6. Configure the capture for the page

Browserless documents controls for full-page capture, output type, viewport or clip settings, element selection, and wait/configuration options. Choose based on the question the screenshot needs to answer:

  • Full page: use when reviewing the whole document; long pages can take longer and produce larger images.
  • Viewport or clip: use when only a specific visible area matters.
  • Element selection: use when the capture should focus on one component.
  • Output type: select among the supported image formats for your downstream use.
  • Wait behavior: allow time for a dynamic page to render before capture. The correct wait depends on the app’s loading behavior.

Consult the current [Screenshot API reference](https://docs.browserless.io/rest-apis/screenshot-api) for exact option names and accepted values; do not assume options from a different Browserless endpoint apply unchanged.

7. Troubleshooting

Symptom Likely cause Fix
Cloud capture of http://localhost:3000 fails or shows the wrong host Localhost refers to the Browserless execution environment. Run execution where the development server is reachable or provide an intentional secured route to it.
Public staging URL does not load DNS, TLS, access policy, or the site’s request handling prevents the hosted browser from loading it. Check the URL from the relevant network, certificate validity, allow rules, and the response from the target.
Self-hosted browser cannot reach another Docker container The containers may not share a network, or the address is being interpreted inside the wrong container. Configure shared Docker networking and use the service address reachable from the browser container.
Connection to private IP is blocked Enterprise URL blocklist policy may block localhost or private destinations. Review the documented blocklist behavior and deployment policy; make any policy change only with a clear understanding of its network implications.
Page loads but shows a login screen The browser session has not completed the app’s authentication flow. Configure and verify the authentication steps supported by your integration and application.
Screenshot is blank or content is missing The page may not have finished rendering, or the chosen capture region may omit content. Review the page’s load behavior, wait configuration, viewport or clip, and element selection.
Request is rejected Endpoint, token, request body, or JSON formatting may be incorrect. Confirm the deployment’s screenshot endpoint and authentication instructions, then inspect the HTTP status and response body.
Request times out The target may be slow or inaccessible from the browser environment. Check network reachability first; then set a client timeout appropriate to the page and use the documented wait controls where needed.

8. Performance, reliability, and cost considerations

  • Network placement is the main reliability dependency. A browser cannot capture a page it cannot resolve or reach. Validate DNS, routes, firewalls, TLS, access rules, and authentication from the execution environment.
  • Dynamic pages need a suitable wait strategy. Waiting too little can produce incomplete content; waiting longer increases request duration. Use the page’s actual rendering behavior to choose.
  • Full-page captures have more work to do. Large documents can take longer to render and transfer than a viewport or focused element capture.
  • Keep credentials out of source code. Use environment variables or your deployment’s secret storage for API tokens, and avoid logging tokenized request URLs.
  • Cost depends on your Browserless account and deployment. The cited documentation establishes API behavior and configuration, not a price or benchmark. Check your account’s current plan and usage terms rather than estimating from unsupported figures.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request returns an image or PDF, and its capture flow accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each step can be turned off. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with the result identified in response headers. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs.

See the ScreenshotNeo API documentation for request options. This example captures a reachable staging URL:

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://staging.example.com \
  -o staging.webp

Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://staging.example.com"},
    timeout=90,
)
r.raise_for_status()
open("staging.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://staging.example.com',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`ScreenshotNeo returned ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('staging.webp', Buffer.from(await res.arrayBuffer()));

Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card.

FAQ

Does running the Browserless MCP server locally make Cloud capture use my local network?

No. Browserless documents that its locally run MCP server still calls Browserless Cloud for browser execution unless configured to use a self-hosted instance. See the [MCP setup guide](https://docs.browserless.io/mcp/browserless-mcp-server/setup).

Can I capture a private staging site without making it public?

Potentially, if the browser execution environment has an authorized route to it and the deployment’s URL restrictions and the application’s authentication allow access. Self-hosting gives control over deployment placement, but does not create network reachability by itself.

Will sending HTML to the screenshot endpoint capture my running local app?

No. The html input renders supplied markup. It is not a tunnel to a local server or a substitute for reaching an authenticated staging site.

Can I use Browserless Cloud with a public staging URL?

Yes, if the hosted browser can resolve and load that URL and the site allows the request. Check DNS, TLS, access controls, and the page’s behavior.