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.
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