ScreenshotNeo

BlogHow-to

Open a New Page with Puppeteer

Create a Puppeteer page with browser.newPage(), choose the right browser context, and handle navigation and cleanup safely.

By the ScreenshotNeo team4 October 20266 min read

To open a new page with Puppeteer, launch or connect to a browser and await browser.newPage(). It returns a Page object that you can navigate and control. The new page belongs to the browser’s default context.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();
  await page.goto('https://example.com');
  console.log(await page.title());
} finally {
  await browser.close();
}

This example uses ES modules and top-level await. Save it as open-page.mjs and run it in a Node.js project with Puppeteer installed. The official Puppeteer getting-started guide follows the same launch, create, navigate, and close sequence.

Install Puppeteer and run the example

  1. Install a current Node.js release supported by your project.
  2. In a new project, run npm init -y.
  3. Install Puppeteer with npm install puppeteer. The puppeteer package downloads a compatible browser during installation. If you use puppeteer-core instead, provide a browser executable path or channel when launching.
  4. Save the code above as open-page.mjs and run node open-page.mjs.

A page is a Puppeteer Page instance, representing one tab-like page. A single browser can have multiple pages. See the Page API reference.

Choose the right way to create the page

Method Where the page lives Use it when
browser.newPage() The browser’s default context You need a straightforward page in the browser’s default session.
context.newPage() A specific browser context You need separate browser state for an automation task, such as isolated cookies and local storage.

browser.newPage() is asynchronous: await it to get the Page. The API accepts optional CreatePageOptions; consult the current Browser.newPage() reference for the supported options in your installed Puppeteer version. For context isolation, create a context and call its newPage() method. Puppeteer documents that cookies and local storage are not shared between browser contexts.

Create a page in an isolated context

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const context = await browser.createBrowserContext();

try {
  const page = await context.newPage();
  await page.goto('https://example.com');
  console.log(await page.title());
} finally {
  // Closes this context and all pages created inside it.
  await context.close();
  await browser.close();
}

Use separate contexts when tasks should not share browser state. Closing a context closes its pages; the default browser context cannot be closed. See the browser management guide and BrowserContext API.

Open a page in an existing browser

If another process started the browser, connect to its WebSocket endpoint and create the page on the returned Browser object. Replace the example endpoint with the endpoint supplied by your browser process or hosting environment.

import puppeteer from 'puppeteer';

const browser = await puppeteer.connect({
  browserWSEndpoint: 'ws://127.0.0.1:9222/your-browser-endpoint',
});

try {
  const page = await browser.newPage();
  await page.goto('https://example.com');
  console.log(await page.title());
} finally {
  // Detach this Puppeteer client; leave the externally managed browser running.
  await browser.disconnect();
}

Use browser.close() when your script owns the browser lifecycle and should shut it down. Use browser.disconnect() when Puppeteer connected to a browser that should keep running. Disconnecting leaves the browser process and its pages open; these operations are not interchangeable. The endpoint must be valid and reachable from the script.

Creating a page does not navigate it. Use the returned Page for navigation and interaction:

const page = await browser.newPage();
await page.goto('https://example.com');

const title = await page.title();
console.log(title);

await page.close();

Closing one page frees that page while leaving the browser available. If the script owns the browser and has finished all its work, close the browser instead. To create several pages, await each call and keep a reference to each result:

const pages = await Promise.all([
  browser.newPage(),
  browser.newPage(),
]);

await Promise.all(
  pages.map(page => page.goto('https://example.com')),
);

await Promise.all(pages.map(page => page.close()));

Parallel creation can be convenient for independent tasks, but it does not guarantee faster completion. Browser and host resources constrain concurrent work. For task isolation, create separate contexts and create pages within them.

Cleanup and reliability

  • Await page creation. Without await, the variable holds a Promise rather than a usable Page.
  • Use try/finally. It gives the script a cleanup path if navigation or page interaction throws.
  • Close what you own. A browser launched by the script should normally be closed at the end. A browser reached with connect() may belong to another process; disconnect unless you intend to shut it down.
  • Keep contexts scoped to a task. Closing a context closes its pages and helps keep browser state separate.
  • Set navigation expectations deliberately. A page can be created successfully while navigation later fails or takes too long. Handle navigation errors separately from page-creation errors.

Launching and keeping browsers open consumes host resources. Reusing an already-running browser can avoid launching one for every task, but the available resources and lifecycle then need to be managed by the owning process. The cited Puppeteer documentation gives no comparative performance figures, so benchmark your workload and environment before choosing a concurrency strategy.

Troubleshooting

Symptom Likely cause What to check
page.goto is not a function The result of browser.newPage() was not awaited, or the variable is not the Page you expected. Use const page = await browser.newPage() and check that the browser or context call succeeded.
Browser launch fails because Chromium cannot be found The expected browser was not installed, or the project uses puppeteer-core without specifying an executable. Check the package installation and browser setup. With puppeteer-core, configure executablePath or channel as supported by your launch configuration.
Connection fails or times out The WebSocket endpoint is invalid, inaccessible, or the remote browser is not running. Use the current endpoint from the browser process, and check network reachability and endpoint lifetime.
Navigation fails after a page is created The URL may be unreachable, or the site may close or reject the navigation. Separate the newPage() call from goto() when diagnosing; inspect the URL and handle navigation rejection.
The browser remains running after the script The script connected to an external browser and called disconnect(), which detaches Puppeteer without shutting down that browser. Have the browser-owning process close it, or use browser.close() only if this script is responsible for its lifecycle.
Pages share cookies or local storage unexpectedly They were created in the same browser context. Create a separate context with browser.createBrowserContext(), then call context.newPage().

Or skip the browser setup

ScreenshotNeo is a website screenshot API: one GET request with a URL returns an image or PDF. Its API accepts the URL directly, so you do not need to launch a browser or create a Puppeteer page. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

ScreenshotNeo removes cookie banners, popups, and chat widgets 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 browser.newPage() open a visible tab on my desktop?

It creates a page in the browser controlled by Puppeteer. Whether that browser is visible depends on how it was launched.

Does opening a page sign in to a website?

Page creation alone does not authenticate you. Authentication depends on the cookies, storage, and other state in the page’s browser context.

Can I create a page without launching a browser in the same script?

Yes. Connect to a running browser with puppeteer.connect(), then call browser.newPage().

Can a browser context be reused for several pages?

Yes. Call context.newPage() for each page that should share that context’s browser state, then close the context when its work is finished.