October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

How to Retrieve JavaScript-Rendered HTML With Puppeteer

Navigate with Puppeteer, wait for a page-specific readiness signal, then use page.content() for the full rendered document or $eval() for one element.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To retrieve the HTML currently rendered by a page in Puppeteer, navigate to the page, wait for the content you need to appear, then call await page.content(). It returns the full document HTML, including the DOCTYPE. For a custom serialization, run document.documentElement.outerHTML with page.evaluate().

Get the rendered HTML for a full page

Install Puppeteer in your project if it is not already installed, then navigate and wait for a condition tied to the content you intend to retrieve. Replace the example URL and selector with values appropriate for the target site.

import puppeteer from 'puppeteer';

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

  // Wait for content rendered by the page's JavaScript.
  await page.waitForSelector('#results');

  const html = await page.content();
  console.log(html);
} finally {
  await browser.close();
}

page.content() returns the full HTML contents of the page, including the DOCTYPE, according to the Puppeteer Page.content() API. The example uses top-level await; use it in an ES module or place the code inside an async function. Puppeteer’s API documentation changes over time, so check the documentation for the version installed in your project.

Choose a wait condition that proves the content is ready

JavaScript-rendered content may appear after navigation completes. Choose a signal that corresponds to the data or element you need, rather than assuming navigation alone means rendering is finished.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Wait for a specific element

When the desired content has a reliable selector, use page.waitForSelector(). It waits for a matching element to be available. For example, replace #results with a selector for the rendered content. See the Puppeteer waitForSelector() API.

Wait for an application-specific DOM condition

For a result list or status that cannot be represented by a single selector, page.waitForFunction() waits until a function evaluated in the page context returns a truthy value.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option
await page.waitForFunction(() => {
  return document.querySelectorAll('.result').length > 0;
});

const html = await page.content();

This condition checks that at least one result element exists; adapt it if the page has a more precise ready state, such as a completed marker or a known minimum count. See the Puppeteer waitForFunction() API.

Wait for a response or network quiet only when it fits

  • page.waitForResponse() can wait for a response matching a URL or predicate. A response arriving does not prove the application has processed it and updated the DOM. See the Puppeteer waitForResponse() API.
  • page.waitForNetworkIdle() waits for network activity to be idle for at least the configured idle time. Network quiet is not necessarily equivalent to the page being ready. Pair it with a content-specific check when possible. See the Puppeteer waitForNetworkIdle() API.

A fixed sleep can finish too early, while an unnecessarily long timeout can hide an incorrect selector or a condition that will never occur. Prefer an explicit readiness condition and handle a timeout as a sign to inspect the page and selector.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Retrieve custom or partial HTML

Serialize the document element yourself

Use page.evaluate() when you want to control the serialization or transform the result in the browser context:

const html = await page.evaluate(() => document.documentElement.outerHTML);

page.evaluate() runs the supplied function in the page context; if the function returns a Promise, Puppeteer awaits it. This serialization returns the document element’s outer HTML. For the full document result that includes the DOCTYPE, use page.content(). See the Puppeteer Page.evaluate() API.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • 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

Extract one matching element

When you only need one element and its descendants, use $eval():

const html = await page.$eval('.content', element => element.outerHTML);

This returns the matched element’s outer HTML, not the whole document. If the selector does not match an element, $eval() throws. See the Puppeteer $eval() API.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Read HTML inside an iframe

An iframe has its own document. The main page’s page.content() does not serialize the iframe’s internal document as part of the parent document’s HTML. Find the relevant frame and call its content() or evaluate() method in that frame’s context.

const frame = page.frames().find(frame => frame.url().includes('frame-path'));
if (!frame) {
  throw new Error('Target iframe was not found');
}

await frame.waitForSelector('.content');
const html = await frame.content();

Change the frame-identifying condition and selector to match the page. See the Puppeteer Frame API.

Do not confuse HTML retrieval with setting content or making a PDF

  • page.setContent(html) sets supplied markup as the page content; it is an input operation, not a way to read the page’s rendered HTML. See the Puppeteer Page.setContent() API.
  • page.pdf() generates a PDF of the page; it does not return HTML. See the Puppeteer Page.pdf() API.

Troubleshoot common retrieval failures

  • The HTML is missing content: Navigation may have finished before the client-side render. Wait for a selector or DOM condition representing the content, then retrieve the HTML.
  • waitForSelector() times out: Check that the selector exists on the page, that you are looking in the right frame, and that the element is expected to appear. If readiness is expressed by some other DOM state, use waitForFunction() instead.
  • $eval() throws: The selector did not match an element at evaluation time. Verify the selector and wait for the target element before calling $eval().
  • The expected content is inside an iframe: Retrieve the corresponding frame and use its frame-context methods; the parent document’s HTML is not the iframe document’s HTML.
  • A response arrived but the HTML is unchanged: A network response alone does not confirm that the page consumed the response or rendered the desired content. Follow it with a DOM readiness check.
  • Network idle never seems to be the right signal: Network activity can be unrelated to whether the target content is rendered. Prefer a selector or application-specific DOM condition when one is available.

Or skip the browser setup

For a screenshot or PDF rather than HTML markup, ScreenshotNeo offers a one-request website screenshot API and an MCP server for AI agents. It does not retrieve rendered HTML, so use Puppeteer above when HTML is the required output. For a screenshot, make a GET request with the target URL:

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 and response details. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Sign up for free.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. Shenzhen desk3 min
    HONOR Expands Beyond Smartphones With Humanoid Robot RevealHONOR said it unveiled its first humanoid robot at MWC 2026 and named shopping assistance, workplace inspections, and supportive companionship as intended uses. Later Robotics D1 claims and a reported…
  2. Cupertino desk5 min
    Apple Unveils AirPods Max 2: The Upgrade That Should Have Happened Years AgoAirPods Max 2 adds H2-powered audio features and Apple claims up to 1.5× more effective ANC, but its design, Smart Case, and 20-hour battery rating are unchanged. Wired lossless audio…
  3. Cupertino desk4 min
    Apple’s OLED Touch MacBooks Are Coming—but the Dynamic Island Is the Real GambleApple has not announced an OLED touchscreen MacBook, but reports point to high-end models arriving in late 2026 or early 2027. The reported Mac Dynamic Island could be useful, but…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.