Complete guide · Published October 18, 2026 · 12 min read
How to Record a Website as Video: Screen Recorders, Code and APIs
Quick answer
To record a website as video once, use your computer's screen recorder (Shift+Command+5 on Mac, the Snipping Tool on Windows 11). To record a website video automatically, for example a smooth scrolling video of a landing page, use Playwright's recordVideo or Puppeteer's page.screencast(), then convert the WebM to an H.264 MP4 with ffmpeg. Avoid GIF for anything longer than a few seconds: it is several times larger than MP4.
"Record a website" covers very different jobs: a quick clip for a bug report, a polished scrolling video of your landing page for social media, an automated recording of a test run, or a video an AI agent makes while it browses. We tested the code in this guide on our own homepage on macOS with Chrome, Playwright 1.64.1, Puppeteer 25.14.0 and ffmpeg 8.0.1, and the file sizes below are from those runs.
Pick your scenario
| You want to | Best method | Output |
|---|---|---|
| Show a bug to a colleague right now | OS screen recorder | MOV / MP4 |
| Record a narrated product walkthrough | Screen recorder or a recording extension | MP4 |
| Make a smooth scrolling video of a landing page | Playwright or Puppeteer + scripted scroll | WebM → MP4 |
| Capture a hero animation or micro-interaction | Playwright with a fixed viewport, short clip | MP4 or short GIF |
| Keep a video of every failed end-to-end test | Playwright Test video option | WebM in the report |
| Record what an AI agent did in the browser | Playwright MCP with DevTools capability | WebM |
| Record many URLs on a schedule | Script in CI, or a video API | MP4 |
| Record a streaming service's DRM-protected player | The protected video area records as black; the rest of the page records normally | See why |
1Built-in screen recorders
| System | How |
|---|---|
| macOS | Press Shift+Command+5, choose "Record Selected Portion", draw around the browser window, click Record. |
| Windows 11 | Open the Snipping Tool, switch to the video (record) mode, select the area and start. |
| Windows (games bar) | Win+Alt+R records the active app window. |
For a cleaner result, hide bookmarks and extensions, set the browser zoom to 100%, close chat widgets and cookie banners first, and scroll with the keyboard (Space or arrow keys) for a steadier motion than a trackpad. Recording extensions such as Loom add webcam and narration on top, which is useful for walkthroughs.
2Playwright: a scrolling video in 20 lines
Run it with node record-scroll.mjs. The 30-second and 20,000-pixel limits stop the loop on pages with infinite scrolling; on our homepage the 30-second limit stopped the scroll before the bottom, giving a 32-second video including the first and last pauses. The demo and the file sizes below come from an earlier run without the limits, which scrolled all the way down in 37 seconds.
Four things we ran into:
- Set
recordVideo.size. Without it, Playwright scales the video to fit 800×800, or uses 800×450 if no viewport is set, so a 1280×720 page comes out smaller. - Close the context. The video file is only finished when
context.close()resolves. Readpage.video().path()afterwards. - The video starts blank. Recording begins when the page is created, before
gotofinishes, so our file opened with about a second of white frames. Trim it when converting withffmpeg -ss 1.2 -i recording.webm .... - ffmpeg is a separate download. It usually comes with browsers installed by
npx playwright install; if you launch system Chrome withchannel: "chrome", recording fails until you runnpx playwright install ffmpeg.
For tests, you do not need the code above. Playwright Test records automatically with use: { video: "retain-on-failure" }, keeping videos only for failed tests (the same modes as traces, such as on-first-retry). Our screenshot-on-failure guide shows how to upload them from CI.
3Puppeteer: page.screencast()
page.screencast() is marked experimental in Puppeteer's types and needs ffmpeg on your PATH. Its options include crop (record part of the viewport), scale, speed (for example 2 for a double-speed video) and fps.
format: "mp4" produced VP9 video inside an MP4 container (ffprobe reported codec_name=vp9). Many editors, social platforms and older devices expect H.264, so re-encode it as shown in the next section before you share it.4Recording what an AI agent does
Playwright MCP, the browser server many coding agents use, can record its own session. Start it with the DevTools capability:
The agent then has browser_start_video and browser_stop_video tools. Without a filename, videos are saved in the output directory as video-{timestamp}.webm. Ask the agent to start recording before a task and stop afterwards; the video is a reviewable record of every click. Details on where files go are in our Playwright MCP screenshot guide.
Convert and compress with ffmpeg
Browsers record WebM (VP8 or VP9). These ffmpeg commands turn a recording into something you can post anywhere:
webm → H.264 mp4 (broad compatibility)Placing -t before -i limits how much of the input is read; placed after -i it limits the length of the output instead.
What these produced for our 37-second, 1280×720 homepage scroll (the run without limits):
| File | Settings | Size |
|---|---|---|
| Playwright WebM | VP9, 1280×720, as recorded | 9.0 MB |
| H.264 MP4 | CRF 23, faststart | 5.7 MB |
| GIF | 640 px wide, 12 fps, palette | 21.7 MB |
-pix_fmt yuv420p is what makes the MP4 play in Safari, QuickTime and most social apps we know of; +faststart lets it start playing before it has fully downloaded. One run on one page, so treat the sizes as an example, not a benchmark. We read sizes and codecs with ls -lh and ffprobe -v error -show_entries format=duration:stream=codec_name,width,height -of compact file.mp4.
Tips for a smooth, clean scrolling video
| Problem | Fix |
|---|---|
| Video looks like a slideshow | Scroll 10 to 20 px per step with ~16 ms between steps instead of jumping by a screen |
| Empty boxes below the fold | Lazy-loaded images only start loading when scrolled near. Do a quick scroll pass before recording, scroll back to the top, then wait for the images you care about (or a specific element) with a timeout. networkidle alone does not help, and on pages with constant requests it may never fire |
| Sections appear late or not at all | Scroll-reveal animations; inject CSS that disables them for the recording |
| Cookie banner covers the page | Accept or reject it before recording, or hide it with injected CSS on your own site |
| Sticky header jumps | Native scroll-behavior: smooth fights scripted scrolling; set it to auto for the recording |
| Video is too long | Speed it up with setpts afterwards instead of scrolling faster, which looks choppy |
Recording website videos through an API
Running browsers and ffmpeg yourself works, but at volume it becomes infrastructure: browser crashes, disk space for raw video, encoding time and queues. A website video API moves that to a hosted service. The model is the same across providers:
- Send the URL and the recording settings: viewport, length, frame rate, output format.
- Describe what should happen on the page: a list of actions such as "wait 1 s, scroll 800 px, click this button, wait 2 s". This replaces the scroll loop in your script.
- Wait for the result. Video takes longer than a screenshot, so APIs usually offer an async mode: you get a job ID, then poll for it or receive a webhook when the file is ready.
- Get the file: streamed back directly, or as a link to stored MP4 or WebM.
| Question to ask a provider | Why it matters |
|---|---|
| Maximum length and frame rate | Longer, smoother videos cost more and take longer to render |
| Codec of the MP4 | H.264 plays almost everywhere; VP9 or HEVC may need re-encoding |
| Which actions are supported | Scroll and click are common; typing, hovering and waiting for elements vary |
| Cookie banners, ads, lazy loading | The same cleanup problems as screenshots, but they are visible for the whole video |
| Async jobs and webhooks | Synchronous requests for long videos can hit HTTP timeouts |
| Pricing unit | Per video, per second of video or per rendering time; compare on your typical length |
Some screenshot APIs already offer scrolling videos as part of their paid plans; our ScreenshotOne comparison notes this, for example. Use cases where an API makes more sense than a script: product pages recorded on a schedule, video previews generated for user-submitted URLs, social clips for many landing pages, and recordings triggered from no-code tools or AI agents.
How video capture is planned in SnapshotFlow
/video do not work today.The idea is the same as our screenshot endpoint: one HTTP request, a hosted browser on our side, and a file back. According to the planned design, GET /video will record a page interaction as MP4 or WebM, replay scroll and click actions during the recording, and follow the same response_type convention as /screenshot: stream the file directly, or return a storage path or an async job_id.
| Planned parameter | Default | Meaning |
|---|---|---|
url | required | Page to record |
duration | 5 s | Recording length, up to 60 seconds |
fps | 25 | Frames per second |
format | mp4 | mp4 or webm |
width / height | 1280 / 800 | Viewport size |
actions | none | JSON list of scroll and click actions to replay, for example [{"type":"scroll","y":800,"delay":1000}] |
A request would look like this once it ships (illustrative, based on the planned parameters):
planned, not liveUntil then, the Playwright script above gives you the same result on your own machine or CI, and our /screenshot endpoint covers full-page images, PDFs and mobile captures today. The roadmap section of the docs and the changelog will show when video lands.
Rights and privacy
- Other people's websites: a video of a page is a copy of its content, so the same copyright rules apply as for screenshots. Recording for internal review is usually low risk; publishing needs permission or a legal exception. See is it legal to screenshot a website.
- Protected video: streaming players use DRM, and their video area records as black. Getting around that is restricted by law in many countries and is not covered here.
- Recording your visitors is different: this guide is about recording pages yourself. Recording real users' sessions on your site (session replay) involves personal data and usually needs consent and a privacy notice.
- Logged-in pages: before sharing a recording of a dashboard, check it for names, emails, tokens and customer data.
Takeaways
- One-off: your OS screen recorder. Repeatable: Playwright or Puppeteer.
- Set Playwright's
recordVideo.sizeand close the context to get the file. - Check Puppeteer's codec and re-encode to H.264 for sharing.
- Prefer MP4 over GIF; our GIF was almost 4× larger at half the size.
- SnapshotFlow's
/videoendpoint is planned, not live.
Sources
FAQ
How do I record a website as a video?
For a one-off, use your operating system's screen recorder: Shift+Command+5 on a Mac or the Snipping Tool's record mode on Windows 11. For repeatable or automated recordings, use Playwright's recordVideo option or Puppeteer's page.screencast() and convert the result with ffmpeg.
How do I make a scrolling video of a website?
Open the page in Playwright or Puppeteer with video recording on, scroll in small steps with a short pause between them, then stop the recording. Small steps of 10 to 20 pixels every frame look smooth; big jumps look like a slideshow.
Why is my Playwright video only 800x450?
If you do not set recordVideo.size, Playwright scales the video to fit 800x800 (or uses 800x450 when no viewport is set). Pass recordVideo: { dir, size: { width: 1280, height: 720 } } to keep the full resolution.
Why won't my Puppeteer MP4 play in some apps?
In our test, page.screencast() with format mp4 produced VP9 video inside the MP4 container. Many tools expect H.264. Re-encode with ffmpeg -c:v libx264 -pix_fmt yuv420p for the widest compatibility.
Should I use GIF or MP4 for a website recording?
MP4 in almost every case. In our test a 37-second scroll was 5.7 MB as H.264 MP4 and 21.7 MB as a GIF at half the resolution and 12 frames per second. Use GIF only for very short loops where video is not supported.
Can SnapshotFlow record videos?
Not yet. A GET /video endpoint is on the SnapshotFlow roadmap and its planned parameters are listed in the API docs. Today SnapshotFlow captures screenshots and PDFs; for video, use one of the methods in this guide.
Need the page as an image today?
Video capture is on our roadmap. Full-page screenshots, PDFs, mobile captures and visual diffs work right now, from one HTTP request. The free tier gives you 300 screenshots, no credit card required.