SnapDOMGitHub8K
How-To Recipe

Capture an iframe as an image

Include a same-origin iframe in an element capture while preserving the frame’s visible viewport and surrounding styles.

TL;DR

Capture the parent container normally. A readable same-origin iframe can be captured from the parent; cross-origin and origin-opaque sandboxed frames cannot.

Copy-paste example

Install @zumer/snapdom, select the rendered element, and capture it:

const panel = document.querySelector('#panel-with-frame')
const image = await snapdom.toPng(panel, {
  placeholders: true,
  embedFonts: true,
})
document.body.appendChild(image)

Why this pattern works

SnapDOM reads an accessible iframe document, captures its visible content and places the result back into the parent snapshot. A cross-origin frame cannot be read, so it is drawn as a striped placeholder of the same size (the default) and a console warning names it; the parent layout never collapses around it.

Capture a same-origin iframe

The embedded srcdoc frame is same-origin and can be included in the parent capture.

SAME-ORIGIN FRAME
The captured result will appear here.

Limits and common mistakes

The same-origin policy prevents code in the parent page from reading an arbitrary third-party iframe document. A frame sandboxed without allow-same-origin has an opaque origin and may be inaccessible even when its URL looks local. SnapDOM cannot bypass either security boundary. For an authorized target, Playwright or Puppeteer can open the document as its own page or evaluate inside the frame's context, inject SnapDOM there and capture it separately. If you only need one composed bitmap of the parent and its frames, the automation tool's native page screenshot is usually the shorter path.

Frequently asked questions

Can I capture a YouTube or third-party iframe?

Not from the cross-origin parent page: the browser blocks that context from reading the frame document. For an authorized target, browser automation can open the document as its own page or evaluate inside that frame context and inject SnapDOM there.

What happens to inaccessible frames?

In a parent SnapDOM capture they become a striped placeholder the size of the frame, so the surrounding layout is unchanged and the unavailable content is explicit. That is the default; pass placeholders: false for an invisible spacer of the same size.

Capture it in the browser

Install SnapDOM and turn the DOM your users already see into a portable image.

Open the demoInstall from npm