n8n + Puppeteer — headless Chrome scraping without the ops
DiffHook drives Puppeteer for you, waits for the DOM to settle, diffs the result against the previous snapshot, and delivers changes to n8n over a signed webhook. No Chromium binary, no Docker image, no restart-on-OOM.
Hosting Puppeteer inside an n8n deployment is a classic footgun: the Chromium binary balloons your image size, workers leak memory after a few hundred runs, and any page change breaks the selector script at 3am. DiffHook pulls the browser into a managed fleet. You describe what to watch once, and n8n sees only the post-render diff — never the browser crashes, never the cold-start latency, never the stealth-plugin version drift.
The complete n8n + DiffHook hub
See every n8n recipe, template, and pricing tier in one place.
Workflow
Wire Puppeteer-rendered diffs into n8n in 5 steps
The browser runs on our side. n8n only sees changes — no cold starts, no zombie Chromium processes.
Expose an n8n webhook
Add a Webhook trigger node to a new or existing n8n workflow, note the production URL. This is the destination DiffHook will POST to when the rendered DOM changes.
Pick html_rendered and the Puppeteer engine
Set type to html_rendered and render.engine to puppeteer. Add wait_for_selector or wait_until: networkidle so DiffHook only snapshots after the page has finished loading JS and data.
Target the right element with a selector
DiffHook runs the CSS selector against the rendered DOM. Use a tight selector (a specific product card, a pricing row, a status banner) so the diff is focused and n8n only fires on the signal you care about.
Create the monitor
POST /v1/monitors with the URL, render config, selector, interval, and a webhook delivery to your n8n URL. DiffHook schedules the Puppeteer runs — you own nothing browser-shaped.
React to change in n8n
When the rendered selector output changes, n8n's Webhook node fires with a signed JSON body: previous_value, current_value, url, detected_at. Verify HMAC, then route the diff to the downstream steps.
API example
Puppeteer-rendered monitor, one POST
render.engine picks the browser. Puppeteer is a good default for sites that specifically test for Chrome-family fingerprints.
POST https://api.diffhook.com/v1/monitors
Authorization: Bearer $DIFFHOOK_API_KEY
Content-Type: application/json
{
"type": "html_rendered",
"url": "https://spa.example.com/pricing",
"render": { "engine": "puppeteer", "wait_for_selector": "[data-ready]" },
"css_selector": "main .plan",
"interval_seconds": 600,
"deliveries": [
{
"type": "webhook",
"url": "https://n8n.yourdomain.com/webhook/spa-pricing"
}
]
}Importable workflow
Start from a ready-made n8n workflow
Template handles the HMAC check, parses the Puppeteer-rendered HTML with HTML Extract, and pushes structured rows to a Notion database. Edit the destination node to suit.
FAQ
n8n Puppeteer — common questions
Puppeteer vs Playwright — which engine should I pick?
Do I need to run my own Chromium anywhere?
How does DiffHook handle pages that lazy-load content on scroll?
Can I pass auth cookies into Puppeteer?
What's the check cadence on rendered monitors?
Related workflows
Also great with DiffHook
n8n + Playwright
The other rendered engine — sometimes one gets past a WAF where the other doesn't.
n8n web scraping
Static-HTML scraping for pages that don't need a browser — cheaper and faster when applicable.
n8n webhook
Verify the HMAC, dedupe deliveries, replay failed events — details on the generic webhook page.
Zapier web scraping
Same rendered engine into Zapier Catch Hooks — identical monitor shape.
Make.com web scraping
Route the post-render diff into Make.com's webhook module for low-code automation.
Replace a scraping script
Migrating from a DIY Puppeteer + cron script? Here's what the managed monitor looks like.
Stop shipping Chromium with your n8n image
Managed Puppeteer fleet, HMAC-signed webhooks, 60-second checks, free tier. Ship to production in minutes.