ScraperFlyAI-ready Web Data API

rendering

Scrape SPA Website API for public single page apps

ScraperFly helps teams scrape public SPA routes by comparing raw HTML with rendered output, then enabling browser execution, waits, sessions, headers, routing, screenshots, or PDFs only when the route state proves they are needed.

Single page apps

Capture the route state after the app finishes rendering

Single page apps can return a valid response while the useful page is still not there. The first HTML often contains a root element, scripts, route containers, and placeholders. The real content appears only after client-side routing, async data loading, hydration, or lazy sections finish in the browser.

ScraperFly helps teams capture public SPA routes with evidence: compare raw HTML and rendered output, wait only when timing matters, choose the response format your workflow can use, and keep full-app crawling, parsing, comparison, and storage in your own system.

app shellroute renderresponse output
Developer testing a public single page app route from initial shell to rendered response output

What is a SPA website scraping API?

A SPA website scraping API captures public single page app routes through a hosted request layer. The API can fetch the initial HTML, execute browser JavaScript when needed, wait for the route state to settle, and return the result as rendered HTML, text, Markdown, JSON metadata, screenshot, or PDF output. Your application still owns route selection, extraction logic, validation, storage, monitoring, and business decisions.

This distinction matters because a single page app is not a normal multi-page site from a scraper's point of view. The URL may resolve, the server may return a 200 status, and the source HTML may still be too thin for the workflow. The useful content can depend on the browser executing the application and loading route data after the first response.

Practical takeaway: scrape SPA routes by proving the rendered page state, not by assuming the first HTML response contains the data.

Why are SPAs harder to scrape than static pages?

Static and server-rendered pages often put useful content directly in source HTML. SPAs frequently do not. They may load route content with JavaScript, reuse one document shell across many views, fetch data after navigation, hydrate components, lazy-load sections, or show a fallback state before the final content appears. A parser built against the initial response may miss the exact content a user sees in the browser.

SPAs also make failures easier to misread. An empty body can be a normal app shell, a timing issue, a redirect, a missing public route, a blocked asset, a region-specific response, or a real target problem. The right workflow compares evidence from source HTML, rendered HTML, screenshots, metadata, final URL, response size, and timing before retrying or escalating.

SPA behavior What it means Best capture decision
Initial HTML is only an app shell The route content is likely built in the browser Test rendered output before writing parser rules.
Rendered DOM contains the target fields Browser execution changes the result Use rendering for that route class.
Rendered view appears late Async data or lazy sections need more time Add wait timing deliberately and log why.
Route output changes by state or region Cookies, headers, sessions, or location may affect the public view Add request context only where samples prove it matters.
Screenshot shows content but parser output is empty The format or extraction logic may be wrong Compare rendered HTML, text, Markdown, and metadata before retrying.

When should ScraperFly render a SPA route?

Render a SPA route when the useful public content appears only after JavaScript runs. That is common for application shells, client-side route transitions, product grids, public dashboards, search results, filter views, lazy article sections, profile pages, and pages that fetch data after the first load. Rendering gives your workflow the page after the browser has built the state.

Rendering should be attached to a route class, not the whole site by default. Some routes may expose useful metadata or server-rendered content in source HTML. Others need rendering and waits. Others need screenshots for visual QA. Treat each representative route as evidence and keep the request profile as light as the route allows.

For framework-specific pages, compare the React and Vue guides: scrape React websites and scrape Vue websites. For broader browser capture decisions, use the JavaScript rendering API.

Which response format should a SPA workflow choose?

Rendered HTML is the right choice when a parser needs the final DOM, links, attributes, route content, tables, cards, or component output. Text and Markdown are useful when the route should feed search, classification, summaries, RAG ingestion, or content review. JSON metadata helps operations because it records status, final URL, content type, response size, and request context. Screenshots and PDFs are useful when people need visual proof of the rendered route.

The output should match the consumer. A monitoring job may need metadata plus a screenshot. A backend parser may need rendered HTML. An AI ingestion flow may prefer Markdown. A review workflow may need a PDF. Choosing this early prevents the team from building converters around the wrong response.

SPA use case Output to test Why it fits Keep in mind
Route DOM parsing Rendered HTML Captures the page after client-side routing and rendering Field extraction still belongs downstream.
AI or content workflows Text or Markdown Returns readable content with less layout noise May not preserve enough structure for selectors.
Debugging and logs JSON metadata Makes response evidence visible to jobs and monitoring Does not replace target-specific parsing.
Visual QA Screenshot Shows whether the route rendered the expected state Heavier than machine-readable output.
Archive or approval PDF Creates a portable record of the rendered page Usually not the best parser input.

How should waits, sessions, headers, and routing be used?

SPAs often need timing control, but waits should solve a real loading problem. Add wait behavior when the route renders before async content, lazy sections, or frontend data calls finish. Use sessions when related public routes depend on shared state. Use headers when legitimate request context affects the response. Use country routing when the route changes by region, language, currency, availability, or redirect behavior. Use stronger delivery only when repeated evidence shows the simple path cannot return a usable page.

The clean pattern is to test one control at a time. If a wait improves the response, keep it tied to that route class. If sessions matter, keep them scoped to related requests. If visual proof is needed, request screenshots where humans actually review the result. Avoid turning every SPA capture into the most expensive possible request.

Use sessions for state continuity, custom headers for request context, and routing controls when delivery path affects the public response.

Does ScraperFly navigate an entire SPA automatically?

No. ScraperFly captures supplied public routes and returns the response in the format you request. Your workflow should decide which routes to visit, how to discover URLs, what fields to extract, how to compare changes, where to store data, and how to handle downstream alerts or analysis. That boundary keeps the promise clear and useful.

This is usually the better architecture. The API handles page capture, rendering, waits, files, formats, and delivery controls. Your system owns the route map and product-specific meaning. If a route is incomplete, you can adjust capture. If parsing fails, you can adjust extraction. The two problems stay separate.

How can SPA scraping stay affordable?

Browser work is heavier than simple HTML capture, so cost control starts with route classification. Keep static or server-rendered routes light. Render routes that prove JavaScript changes the result. Add waits only when async content needs them. Reserve screenshots, PDFs, sessions, country routing, and stronger delivery for workflows that actually use those controls.

ScraperFly supports that path because you can start free, test representative SPA routes, buy credits for uneven projects, and move recurring workloads to monthly credits once the page mix is known. The buying decision becomes easier when the team knows which routes are light, which are rendered, and which require extra proof or routing.

Review pricing after sampling real SPA routes so the estimate reflects actual request profiles rather than blanket assumptions.

Where should a team start?

Start in the API Builder with one real public SPA route. Request source HTML first. If the content is missing, enable rendering and compare the output. Add waits only if the rendered route still captures too early. Then choose the format your workflow needs: rendered HTML for parsers, Markdown or text for readable content, JSON metadata for logs, screenshot or PDF for visual proof.

Once the request profile is proven, move it into cURL, Python, Node.js, a backend queue, monitoring job, or agent workflow. Keep that profile visible so future failures can be debugged from response evidence, not guesses.

SPA scraping

Capture single-page apps after the browser builds the useful state

Single-page apps often return an empty shell first, then load routes, cards, tables, filters, and content through JavaScript. ScraperFly helps teams test raw HTML against rendered output and choose the smallest request profile that captures the real page state.

Raw HTML response mapped to visible page data
01

Raw HTML availability

Check whether the fields you need are already present in the first HTML response.

Best first test for simple pages, articles, docs, listings, and product details.

Before and after JavaScript rendering comparison
02

JavaScript dependency

Compare raw HTML with the rendered DOM or screenshot before turning on browser rendering.

Use rendering when raw HTML is only a shell and scripts create the useful content.

Cookies, consent, session and access context for scraping
03

State & access context

Identify whether cookies, consent, login boundaries, pagination, or the same visitor state affect the response.

Use sessions and headers when continuity changes the data you receive.

Regional content variations across countries and routes
04

Geo/content variation

Test whether country, language, currency, inventory, SERP, ads, or route reputation changes the result.

Use geo or premium routing only when the target proves the response varies by route.

Checks before scraping SPAs

Where is the target field?

Find whether the field exists in raw HTML, rendered DOM, an API call, structured data, a file, or a later interaction state.

What changes the response?

Sample a few URLs and compare status, final URL, content length, redirects, empty states, and visible result differences.

What context is required?

Mark any dependency on consent, locale, cookies, headers, authentication boundary, pagination, filters, or previous requests.

What does failure look like?

Define the signals for blocked, partial, stale, redirected, empty, timed-out, or region-mismatched responses before scaling.

How SPA behavior changes scraping setup

Fetch mode

Raw HTML availability decides whether the first request can stay simple or needs rendering, waits, screenshots, or extraction.

Request context

State requirements decide whether to add headers, cookies, sessions, consent handling, or a stable visitor profile.

Routing choice

Geo and reputation findings decide whether standard routing is enough or a country/premium route is justified.

Validation rules

Known failure states become checks for retries, escalation, QA review, and deciding when a lighter profile is still complete.

SPA request builder

Build a scraping request for client-side routes, lazy content, and rendered output

Start with a simple page capture, then add rendering, waits, sessions, headers, country routing, premium delivery, screenshots, or PDFs when the app needs more context to produce useful content.

APP
Route state

Render client-side routes when source HTML is only a shell

Browser execution helps expose app content that appears after routing, hydration, async data calls, or lazy sections.

render=truewait
QA
Visual proof

Verify the page state before trusting parsed output

Screenshots and PDFs help confirm whether the app rendered the expected view, filters, content, and layout.

screenshotpdf
API
API workflow

Move the proven request shape into production

Once the target behavior is clear, the same request controls can move into cURL, Postman, Python, Node.js, or backend services.

curlpostmanbackend

Controls that matter for SPA scraping

url

The SPA route or public page being captured.

render

Browser execution for client-side application state.

wait

Timing control for async data and lazy sections.

format

HTML, text, Markdown, JSON, screenshot, or PDF output.

cURL example

Generate Markdown with the same request shape you can move into production

curl "https://scraperfly.com/api/v1?url=https%3A%2F%2Fexample.com&format=markdown" \
  -H "apikey: YOUR_API_KEY"

Error handling

Turn scraping failures into fixes

Every web data workflow eventually meets a bad response: a missing URL, an invalid key, an empty HTML shell, a target 403, a rate limit, a render timeout, a broken PDF capture, or a JSON payload that does not contain the fields your product expected. ScraperFly is built to make those moments diagnosable. You inspect the HTTP status, the stable error code, the request profile, and the returned artifact, then choose the cheapest useful next move: fix the request, add credits, slow down, retry with backoff, enable rendering, change country, use premium routing, preserve headers, or validate the output before scaling.

Stable error shapeRetry decisionsCost-aware escalationOutput validation
Developer reviewing code and API request parameters on a laptop

01 / Request setup and access

Fix request mistakes first

Some failures are not target problems at all. They happen before ScraperFly can make a meaningful delivery attempt: a missing or malformed URL, an unsupported output format, an incompatible visual file type, a missing API key, an invalid key, or a key that has been paused or disabled. These errors are configuration signals, not retry signals: stop the workflow, point the developer to the exact field that needs correction, and keep credits focused on real target tests instead of repeated bad inputs.

missing_urlinvalid_urlunsupported_formatinvalid_api_key
  • Validate the URL and encoding before sending a batch.
  • Use supported outputs: HTML, text, Markdown, JSON, screenshot, or PDF.
  • Match screenshot file types to image output and PDF file type to PDF output.
  • Treat missing or invalid API keys as configuration work, not retry work.
Business dashboard with charts, documents and usage planning on a desk

02 / Credits, limits and concurrency

Separate limits from failures

A workload can fail because the account has no usable credits, the monthly plan limit has been reached, or concurrency is too aggressive for the current plan and target mix. ScraperFly makes those limits visible as operating signals, not mysterious scrape failures. That keeps the buying decision practical: start free, test the target, buy pay-as-you-go credits for uneven jobs, move to monthly credits when volume becomes predictable, and use backoff when request pressure is the real issue.

usage_limit_reachedrate_limitedcreditsbackoff
  • Use account status to check remaining credits before large runs.
  • Retry rate limits with backoff instead of immediately increasing pressure.
  • Keep one-off projects on pay-as-you-go when volume is uneven.
  • Move predictable recurring work to monthly credits when the pattern is proven.
Server room representing delivery paths, routing and network infrastructure

03 / Target delivery and network

Find delivery failures first

Many scraping platforms collapse delivery issues into a vague request failure. In production, that is not enough. The team needs to know whether the request timed out, the upstream target returned a temporary server error, the connection failed, the response was too large, redirects went somewhere unexpected, or the page came back as tiny HTML with no useful content. ScraperFly turns those failures into delivery evidence: try the light profile first, compare status and response size, then decide whether the next request needs backoff, another route, premium proxy, country targeting, or a narrower capture.

timeout5xxredirectsresponse_too_large
  • Retry temporary network and upstream failures with a controlled backoff policy.
  • Compare final URL, status, content type and response size across samples.
  • Escalate routing only when the response proves the simple path is unstable.
  • Treat oversized responses as a scope problem before scaling the same profile.
Digital security screen representing anti-bot and protected access signals

04 / Anti-bot, geo and access blocks

Read blocks before escalation

A target 403, 401, 429, CAPTCHA screen, WAF challenge, login wall, consent loop, or region-specific mismatch is not just an error; it is a clue about what the site expects from the visitor. Competitors often push teams toward a heavier default profile, but that can burn budget without proving the fix. ScraperFly's better path is evidence-based escalation: preserve realistic headers when context matters, use sessions when continuity changes the response, enable rendering when the useful content is browser-built, and choose premium or country routing when reputation or geography changes the result.

403429CAPTCHAcountry mismatch
  • Use premium routing when IP reputation is the proven bottleneck.
  • Use country targeting when language, currency, inventory or search results change by market.
  • Use headers, cookies and sessions when visitor state changes the response.
  • Reduce concurrency and add backoff when repeated requests trigger target throttling.
Developer preparing code and output artifacts on a laptop

05 / Rendering and output quality

Ship usable artifacts

A 200 status is not the same thing as a usable scrape. The raw HTML can be an empty app shell, Markdown can miss the main article, JSON can lack expected metadata, text can include noise, screenshots can be blank, and PDF or image output can fail if the browser step times out. ScraperFly is valuable because the same API request can move from raw HTML to rendered DOM, clean text, Markdown, JSON, screenshot or PDF, then be checked against the artifact your product actually needs. That reduces glue code, failed imports, and expensive batch runs that only discover bad output after the fact.

render_timeoutbrowser_render_failedJSON fieldsPDF/image output
  • Enable rendering when raw HTML is only a shell and the useful content appears after JavaScript.
  • Validate text, Markdown and JSON against expected fields before batching.
  • Use screenshot or PDF output when visual proof or audit evidence matters.
  • Treat blank or partial artifacts as quality failures even when HTTP status is successful.
ScraperFly fit

Cleaner error recovery

ScraperFly helps teams decide what to fix, what to retry, and what to escalate without turning every scrape into the most expensive request profile.

Stable error shape

Use HTTP status and error code together so application logic can choose between fixing input, refreshing credentials, slowing down, retrying, or escalating delivery.

Retry only when it helps

Network failures, rate limits, and temporary server errors can use backoff. Invalid URLs, unsupported formats, and bad keys should be corrected once.

Cost-aware escalation

Start with the light request profile, then add rendering, premium routing, country, sessions, headers, waits, or visual capture only when the failure proves it.

Validate output before scale

Confirm the real artifact your product needs: HTML, text, Markdown, JSON, screenshot, or PDF, before copying the same profile across a large URL set.

SPA cost

Use browser work where it unlocks content, not as a blanket default

SPAs often need rendering, but not every route needs the same waits, routing, sessions, or visual proof. ScraperFly keeps request controls modular so teams can pay for the profile that actually works.

A lightweight HTML request returning a simple response
01

Basic fetch

Use a basic fetch when public HTML already contains the fields you need.

Lightest request profile; keep it when the response is complete.

JavaScript rendering producing a complete DOM
02

Rendering

Use rendering when raw HTML is a shell and JavaScript completes the page.

Heavier profile; use it only when browser output changes the result.

Several requests preserving cookies and visitor state
03

Stateful session

Use sessions when cookies, consent, locale, or pagination change the response.

Heavier state profile; preserve it only when continuity matters.

Request routing through geo and higher quality routes
04

Premium routing & geo

Use premium routing or geo only when origin, country, reputation, or regional content changes the result.

Heaviest routing profile; apply it only to targets that prove they need it.

What makes SPA scraping heavier

More infrastructure work

Browser rendering, routing choices, and longer waits mean the platform has to do more than return a simple response.

More target uncertainty

Redirects, empty states, rate limits, and challenge pages often require stronger delivery options or retries.

More state to preserve

Cookies, sessions, consent, and multi-page flows add moving parts that a plain stateless fetch does not have.

More evidence to return

Screenshots, PDFs, rendered output, and richer response artifacts are useful, but they are heavier than plain HTML.

How to control SPA scraping cost

Sample before scale

Test a small URL set first and group targets by the lightest profile that returns complete data.

Do not render by default

Inspect raw HTML before turning on rendering. Many public pages already contain the data you need.

Escalate by evidence

Move up only when the response shows missing content, state dependency, geo variance, or routing problems.

Measure useful results

Optimize around valid records delivered, not raw request volume. A lighter profile is best only when it stays complete.

SPA questions

Common questions about scraping single page apps

Practical answers for teams deciding when SPA routes need rendering, waits, visual proof, request context, and downstream extraction logic.

SPA FAQ
Routes

App shells and route state

SPAs often need rendered evidence before parsing makes sense.

What is a SPA website scraping API?

It is an API workflow for capturing supplied public single page app routes, often with browser rendering enabled when the route content is built client-side.

Why are SPAs harder to scrape?

SPAs often load route content in the browser after the first HTML response, so raw HTML can be incomplete.

Rendering

Browser execution and waits

Rendering and waits should solve proven route issues.

Can ScraperFly render SPA routes?

Yes. ScraperFly can render public SPA pages when JavaScript is needed to expose the route content.

When should I add wait timing?

Add waits when the rendered route captures before async data, lazy sections, or frontend requests finish loading.

Formats

Outputs for SPA workflows

Rendered routes can support parsers, content systems, QA, and archives.

Which formats are useful for SPA scraping?

Rendered HTML supports parsers, text and Markdown support review, JSON metadata supports logs, and screenshots or PDFs preserve visual proof.

Can visual proof help with SPAs?

Yes. Screenshots and PDFs help confirm whether the app rendered the expected route, filters, content, and layout.

Scope

What remains downstream

The API captures the route; your workflow owns navigation and extraction.

Does ScraperFly navigate entire SPAs automatically?

No. ScraperFly captures supplied public routes. Route discovery, crawling strategy, extraction, comparison, and storage remain downstream.

How can SPA scraping stay affordable?

Classify routes and reserve rendering, waits, sessions, visual files, or stronger routing for route classes that prove they need them.