A rendered HTML API returns the DOM markup that exists after a browser has loaded a page and run its JavaScript. That is different from downloading the original HTTP response, which may contain only an application shell such as an empty <div id="app">. You can obtain this post-render HTML through a managed HTTP endpoint such as Zyte’s browser-rendered API or Browserless’s /content endpoint, or by launching a browser with Playwright or Puppeteer and calling page.content().
What “rendered HTML” actually means
The initial response from a modern site is often not the final document. JavaScript may fetch products, insert article text, expand menus, authenticate a session, or replace placeholder elements. A rendered HTML service runs that page in a browser and serializes the resulting Document Object Model (DOM) as an HTML string. Zyte defines browser HTML as the HTML representation of a webpage DOM after it has been rendered in a browser.
The result is useful when your downstream system needs markup: archival, testing, migration, indexing, or conversion to another format. It is not automatically the same as clean semantic data. If you need selected fields as JSON, use a structured extraction endpoint instead. Browserless documents /content for full rendered HTML and /scrape for selector-based JSON.
Choose a retrieval method
| Method | Best for | What you operate | Important limits to check |
|---|---|---|---|
| Managed HTTP API | One request/response integration | Your HTTP client and provider account | Provider-specific request methods, headers, browser timeouts, iframe and shadow-DOM behavior |
| Playwright or Puppeteer | Branching workflows and detailed browser control | Browser binaries, concurrency, sessions and failures unless using hosted CDP | Navigation waits, memory, anti-bot behavior and your own timeout policy |
| Hosted browser via CDP | Library control without hosting browsers | Automation code; provider infrastructure | Provider pricing, connection limits and browser policy |
Use a managed endpoint for a straightforward fetch. Choose direct Playwright or Puppeteer when the workflow must decide what to click, type, scroll, or capture next. Before committing, verify the service’s initial request semantics, action timeout, iframe handling and whether shadow-DOM content is exposed.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →#1 Best Overall
Managed APIs that return browser HTML
Zyte browser-rendered HTML
Zyte’s extraction API accepts a URL with browserHtml: true and returns a browserHtml string. A minimal request conceptually looks like this:
POST https://api.zyte.com/v1/extract
Content-Type: application/json
{
"url": "https://example.com/article",
"browserHtml": true
}
Read the browserHtml property from the JSON response. Zyte also supports browser actions such as typing, clicking, scrolling and waiting before the HTML is returned, which is essential for content hidden behind interaction. Its documented browser requests restrict the initial request: arbitrary methods, bodies and initial-request headers other than Referer are not supported, although subsequent browser activity can make additional requests. Browser action execution has a documented 60-second limit.
Browserless /content
Browserless exposes a REST /content endpoint that returns fully rendered HTML without requiring a Puppeteer or Playwright client library. This is a practical option when your application already speaks HTTP and you want the provider to manage browser processes. Use its separate /scrape path when the desired output is structured JSON selected through CSS selectors rather than the complete document.
Self-managed retrieval with Playwright
Playwright’s page.content() serializes the current DOM. Install the package and a browser, navigate, wait for the state your page requires, then save the string.
Recommended Free Tools
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
npm install playwright
npx playwright install chromium
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({
viewport: { width: 1440, height: 900 }
});
try {
await page.goto('https://example.com/article', {
waitUntil: 'domcontentloaded',
timeout: 60000
});
await page.waitForLoadState('networkidle', { timeout: 30000 }).catch(() => {});
await page.locator('article').waitFor({ state: 'visible', timeout: 15000 }).catch(() => {});
const renderedHtml = await page.content();
console.log(renderedHtml);
} finally {
await browser.close();
}
domcontentloaded prevents an unnecessarily long wait for every network request. Add a selector wait for the actual content you need; use networkidle only when it is meaningful for that site, because analytics and long polling can keep a page busy indefinitely. The selector wait above is deliberately tolerant: if a site has no article element, the script still returns whatever rendered DOM exists.
Self-managed retrieval with Puppeteer
npm install puppeteer
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({ headless: 'new' });
const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900 });
try {
await page.goto('https://example.com/article', {
waitUntil: 'domcontentloaded',
timeout: 60000
});
await page.waitForSelector('article', { visible: true, timeout: 15000 }).catch(() => {});
const renderedHtml = await page.content();
process.stdout.write(renderedHtml);
} finally {
await browser.close();
}
The same pattern works when Puppeteer connects to a hosted browser over Chrome DevTools Protocol: navigation and page.content() remain in your code while the provider supplies the browser.
Interaction, frames and shadow DOM
Clicking, typing and scrolling
Render only after the state you need is reached. In Playwright, perform actions before calling content():
await page.getByRole('button', { name: 'Load more' }).click();
await page.locator('.results > article').last().waitFor();
await page.mouse.wheel(0, 1200);
const html = await page.content();
Managed services differ in how actions are expressed, so confirm their action syntax and maximum duration. A consent dialog, login form or infinite-scroll trigger may require a precise sequence rather than a generic delay.
Rank #3
Iframes
A returned HTML string can omit iframe contents. Zyte states that iframes are empty by default in browser HTML. If the required data lives in a frame, inspect that frame separately with automation or use the provider’s documented actions and frame support; do not assume the parent document contains the child DOM.
Shadow DOM
Shadow roots are not always serialized into ordinary outer HTML. Zyte directs shadow-DOM use cases to browser actions. With Playwright, query the component through its supported locators or evaluate the relevant shadow root, then extract the specific markup you need.
Rendered HTML versus structured extraction
Rendered HTML preserves the page’s post-JavaScript markup, including elements you may not care about. Structured extraction returns selected values and is usually easier to validate and store. Choose rendered HTML when you need the document itself—for example, to archive or pass into an HTML-to-PDF pipeline. Choose selector-based JSON when you need fields such as title, price and author and want a stable schema.
Reliability and performance practices
- Use explicit readiness signals. Prefer a selector, a known application state or a completed action over a fixed sleep.
- Set layered timeouts. Give navigation, each action and the overall job separate limits so one stalled resource cannot consume a worker forever.
- Reuse browsers carefully. Keep one browser process and create isolated contexts or pages per job; close pages in a
finallyblock. - Control concurrency. Browser tabs consume CPU and memory. Start conservatively, measure queue time and increase parallelism only when the host remains stable.
- Record diagnostics. Store the final URL, HTTP status, timing, console errors and a screenshot or trace for failures. Never log cookies or authorization headers.
- Make retries selective. Retry transient navigation and provider errors with backoff. Do not repeatedly retry deterministic 404s, login failures or bot challenges.
- Respect access requirements. Authentication, robots policies, rate limits and legal restrictions still apply to rendered requests.
Cost and service limits
Managed-browser pricing is provider-specific and changes over time. Zyte’s pricing page checked on September 29, 2026 displayed browser-rendered ranges of $1.01–$16.08 per 1,000 requests pay-as-you-go, $0.75–$12.00 with a $100 monthly minimum, $0.60–$9.60 with a $200 minimum, and $0.48–$7.68 with a $500 minimum. The amount varies by site-complexity tier, and the page asks for a target URL for site-specific pricing. Verify the live price before budgeting.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #4
- 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
Also account for browser action limits, bandwidth, concurrency, storage and retries. A request that loads a complex application can cost more operationally than a static page even when both produce one HTML string.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting rendered HTML
The HTML contains only an app shell
Cause: capture occurred before the data request completed, or the page failed in the browser. Fix: wait for a content selector, inspect console and network errors, and confirm the final URL. Increase the timeout only after identifying a real readiness condition.
Content appears in the browser but not in the returned string
Cause: the content is inside an iframe or shadow root. Fix: extract the frame separately or use the component’s shadow-root API and provider-specific actions.
The request times out
Cause: third-party requests, long polling or an action sequence exceeds the service limit. Fix: block nonessential resources where supported, replace network-idle waits with a selector wait, and keep action sequences within the provider’s documented limit. Zyte documents a 60-second browser-action limit.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsBest Value
A click does nothing
Cause: an overlay, cookie dialog, wrong frame or non-visible element intercepts the click. Fix: dismiss consent UI, target the correct frame, wait for visibility and verify that the expected DOM change occurred.
Automation receives a bot check or blank page
Cause: the destination is challenging automated browsers or failed to load. Fix: treat the result as a failed capture, inspect the provider’s status, and do not infer that missing content is the real page.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. It is useful when the deliverable is a reliable visual capture rather than the DOM string discussed above, and it can also produce PDFs. One GET request returns PNG, JPEG, WebP or PDF:
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 documentation for all options. Before capture it accepts cookie or consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Frequently asked questions
Frequently Asked Questions
Does rendered HTML include the original server response?
It returns the browser’s current DOM serialization, which may differ substantially from the initial response after scripts add, remove or replace elements.
Can I use rendered HTML for data extraction?
Yes, but complete markup is often more work to parse than a structured extraction endpoint that returns selected fields as JSON.
Why is a fixed sleep unreliable?
A page may finish sooner, take longer, or remain active because of analytics and long polling. A selector or application-state check is a better readiness signal.
Is ScreenshotNeo a replacement for a DOM API?
No. ScreenshotNeo is optimized for screenshots and PDFs, while Playwright, Puppeteer, Zyte browser HTML and Browserless content endpoints return or expose rendered markup.
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 reinstallQuick 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.

