English | 简体中文
SnapDOM
SnapDOM is a browser capture engine for web interfaces. It captures rendered DOM state as a reusable result, with styles, fonts and images included.
Export images and canvas with the core. Use plugins for self-contained HTML, page context, maps for visual agents, PDF and recordings. Captures can also feed WebGL textures, visual regression tests and UI transitions. Everything runs in the page, using standard Web APIs, with no core dependencies.
Documentation and demos · Technical features · Official plugins · 简体中文
This checkout documents v3.x.x. The migration guide below compares it with v2.x.x. The v2 source and v2 documentation remain available.
What you can build
| Use | Output | Provided by |
|---|---|---|
| Share a card, chart, invoice or dashboard | SVG, PNG, JPG, WebP, canvas or Blob | Core |
| Reuse a capture in a texture, overlay or transition | Canvas plus capture geometry | Core |
| Save a page fragment for later display | HTML with captured styles and fonts | html-export plugin |
| Give an agent or a log a view of page content | Text/JSON context, or an image with an element map | context-export / agent-map plugins |
| Download a document or record changing content | Image-based PDF, animated GIF or browser-encoded video | pdf-image / gif-export / video-export plugins |
Image, HTML and context exports use the captured state. GIF and video plugins record the live element over time.
Quick start
import { snapdom } from '@zumer/snapdom';
const card = document.querySelector('#card');
const image = await snapdom.toPng(card);
document.body.appendChild(image);
Capture once when you need several outputs:
const result = await snapdom(card);
const image = await result.toPng();
const canvas = await result.toCanvas();
const blob = await result.toBlob({ format: 'png' });
await result.download({ format: 'jpg', filename: 'card' });
The result keeps that capture even if the source element later changes. Call snapdom(card) again to capture its new state.
Installation
Install the core and, when you need them, the official plugins; use matching major versions:
npm i @zumer/snapdom@latest @zumer/snapdom-plugins@latest
Or load it in a browser:
<script src="https://unpkg.com/@zumer/snapdom@latest/dist/snapdom.js"></script>
<script>
snapdom.toPng(document.querySelector('#card')).then(image => {
document.body.appendChild(image);
});
</script>
As an ES module from a CDN:
import { snapdom } from 'https://esm.sh/@zumer/snapdom@latest';
import { htmlExport } from 'https://esm.sh/@zumer/snapdom-plugins@latest/html-export';
https://unpkg.com/@zumer/snapdom@latest/dist/snapdom.mjs serves the same module. These examples load the latest published core and plugins.
To run the docs site against a local build of this checkout instead:
npm install
npm run compile
npm run site
The local site runs the local build. The public site's demos load the published package.
Build outputs
| File | Use |
|---|---|
dist/snapdom.mjs |
ES module for imports and bundlers |
dist/snapdom.js |
Script tag exposing window.snapdom |
types/snapdom.d.ts |
TypeScript declarations |
There is no CommonJS build. @zumer/snapdom/plugins and the package root share the same runtime and plugin registry.
Usage
Choose an output
| Result method | Returns |
|---|---|
toPng(), toJpg(), toWebp() |
An HTMLImageElement |
toSvg() |
An SVG-backed HTMLImageElement |
toCanvas() |
An HTMLCanvasElement |
toBlob() |
An SVG Blob unless a format was explicitly set on the capture or export |
toRaw() / url |
The capture's SVG data URL |
download() |
Downloads the chosen format |
to(name, options?) |
Runs a core or plugin exporter by name |
One-step shortcuts such as snapdom.toPng(element, options) capture and export in one call. Results also have toJpeg() as an alias for toJpg(). toImg() remains available; prefer toSvg() for an SVG image.
Set size and content
const result = await snapdom(card, {
width: 800,
dpr: 1,
backgroundColor: '#ffffff',
exclude: '.capture-ignore',
excludeMode: 'remove'
});
width and height define output size. If only one is set, the aspect ratio is preserved. scale applies when neither is set, and dpr multiplies the pixel dimensions.
| Common option | Default | Purpose |
|---|---|---|
scale / dpr |
1 / device pixel ratio |
Output resolution |
width / height |
Unset | Output dimensions |
embedFonts |
'auto' |
Embed the web fonts the capture uses |
backgroundColor |
Transparent; white for JPG/WebP | Output background |
exclude |
None | Selectors or predicates; true means exclude |
excludeMode |
'hide' |
Keep an invisible spacer, or use 'remove' |
filter |
None | Predicate; true keeps a node and false filters it out |
filterMode |
'hide' |
Independent layout mode for nodes rejected by filter |
clip |
Unset | Capture the viewport or a page-coordinate rectangle |
captureSelection |
false |
Include the user's text selection |
canvas |
Unset | Reuse an existing canvas |
invalidate |
false |
Refresh after changes such as programmatic CSSOM edits |
fast |
true |
false keeps the page responsive during long captures |
All options include shadows, transforms, fonts, CORS, fallbacks and layout reconciliation.
Export HTML or structured context
Official plugins are published separately as @zumer/snapdom-plugins and must match the core major version; they declare a peer dependency on a v3 core. Their sources live in packages/plugins/ in this checkout.
import { htmlExport, contextExport } from '@zumer/snapdom-plugins';
const result = await snapdom(card, {
plugins: [htmlExport(), contextExport({ format: 'json' })]
});
const html = await result.toHtml();
const context = await result.toContext();
The same plugin system supports overlays, redaction and custom exporters. Local plugins override global plugins by name. See the official plugin reference and plugin specification.
Capture HTML strings
const result = await snapdom.fromString('<article>Hello</article>');
const image = await result.toPng();
fromString() mounts the markup offscreen and removes it after capture. The string is parsed and activated like markup you wrote yourself: inline handlers such as `` run in the caller's origin, and can keep running after the mount is removed. Sanitize untrusted HTML first, with DOMPurify or equivalent.
Feed a WebGL texture
const canvas = document.createElement('canvas');
const texture = new THREE.CanvasTexture(canvas);
texture.colorSpace = THREE.SRGBColorSpace;
async function refresh(element) {
await snapdom.toCanvas(element, { canvas, scale: 1, dpr: 1 });
texture.needsUpdate = true;
}
result.meta contains the capture geometry needed to place an exported ima