n8n + Playwright — JS-rendered scraping without the browser fleet
DiffHook runs Playwright for you on every check, waits for the page to finish rendering, diffs the result, and POSTs changes to n8n over a signed webhook. No headless Chromium to install, no stealth plugins to patch.
Scraping a React or Vue SPA from n8n usually means stitching together the Browserless node, a custom Docker image with Playwright installed, or a third-party scraping API with its own auth and rate-limit dance. All of them put a browser inside your n8n deployment. DiffHook flips the model: the browser runs on our side, fully managed, and only the diff crosses the wire — everything else stays the same simple n8n webhook pattern.
The complete n8n + DiffHook hub
See every n8n recipe, template, and pricing tier in one place.
Workflow
Wire Playwright-rendered diffs into n8n in 5 steps
No Docker image, no Browserless credit, no Playwright install. The browser runs inside DiffHook.
Expose an n8n webhook
Create or reuse an n8n workflow with a Webhook trigger node. Copy the production URL — DiffHook will deliver to it whenever the rendered DOM changes.
Pick html_rendered and the Playwright engine
Set type to html_rendered and render.engine to playwright. Add wait_for_selector or wait_until: networkidle so DiffHook snapshots only once the client-side app has settled.
Isolate the target with a CSS selector
After Playwright finishes rendering, DiffHook runs the selector against the resolved DOM. A tight selector keeps the diff focused and avoids n8n workflows firing on unrelated UI changes.
Register the monitor
POST once to /v1/monitors with the URL, render config, selector, interval, and the n8n webhook as a delivery. DiffHook schedules the browser runs and caches the last-good DOM.
Receive the post-render diff in n8n
On every change, n8n's Webhook trigger fires with previous_value, current_value, and render metadata. Verify HMAC, then route the diff to downstream nodes exactly as you would for a static page.
API example
Playwright-rendered monitor, one POST
render.engine picks the browser — swap to puppeteer any time. wait_for_selector keeps the snapshot stable on JS-heavy pages.
POST https://api.diffhook.com/v1/monitors
Authorization: Bearer $DIFFHOOK_API_KEY
Content-Type: application/json
{
"type": "html_rendered",
"url": "https://spa.example.com/dashboard",
"render": { "engine": "playwright", "wait_for_selector": ".data-loaded" },
"css_selector": "#metric-value",
"interval_seconds": 600,
"deliveries": [
{
"type": "webhook",
"url": "https://n8n.yourdomain.com/webhook/rendered-change"
}
]
}Importable workflow
Start from a ready-made n8n workflow
The template verifies the HMAC, pulls the extracted text out of the rendered DOM, and posts a neat summary to Slack. Import, paste your key, done.
FAQ
n8n Playwright — common questions
When should I choose Playwright over the plain HTML engine?
How does DiffHook decide the page has finished rendering?
Can I pass custom headers or cookies to Playwright?
Is Playwright heavier on my plan limits?
What about CAPTCHAs and bot protection?
Related workflows
Also great with DiffHook
n8n + Puppeteer
Same rendered-scraping pattern with Puppeteer — useful when a site behaves differently under Chromium.
n8n web scraping
Static-HTML scraping for pages that don't need a browser — cheaper and faster when it applies.
n8n webhook
Dig into HMAC verification, retries, and replay on the generic n8n-webhook page.
Zapier web scraping
Same rendered engine, Zapier as the destination — identical monitor shape, different webhook URL.
Make.com web scraping
Pipe the post-render diff into Make.com's webhook module for low-code routing.
Replace a scraping script
Migrating from a Playwright + cron script? See what the managed monitor looks like side-by-side.
Stop hosting a browser just to diff a page
Rendered scraping, Playwright and Puppeteer engines, HMAC-signed webhooks, free tier. Start in under a minute.