
snapDOM is a zero-dependency JavaScript DOM capture library that converts rendered HTML elements into SVG, PNG, JPG, WebP, Canvas, or Blob output.
It captures computed styles, images, web fonts, pseudo-elements, open Shadow DOM, and same-origin iframe content, with reusable captures for multiple exports.
The core handles image and canvas exports. The official plugin package extends captured state to HTML, structured context, element maps, PDF, GIF, video, ASCII, redaction, and capture effects.
If you want to turn captured UI screens back into code, try this screenshot-to-HTML AI tool.
Features
- SVG, PNG, JPG, WebP, Canvas, Blob, and downloadable file output.
- Computed styles, pseudo-elements, images, backgrounds, inline SVG, and scroll state are captured.
- Web fonts used by the captured subtree are embedded automatically.
- Open Shadow DOM and same-origin iframe content are captured.
- Selectors, predicates, clipping, text selection, and layout modes control captured content.
- Eligible unchanged captures are reused, with incremental recapture for safe local DOM changes.
- HTML strings can be captured through
snapdom.fromString(). - Official plugins extend exports, redaction, context extraction, recording, and capture effects.
See It In Action:
Use Cases
- Generate downloadable share cards from rendered HTML components.
- Export invoices, reports, dashboards, and charts as images or canvas content.
- Create thumbnails and previews for editors, builders, and generated layouts.
- Feed captured UI state into PDF exports, regression tests, overlays, and WebGL textures.
How to Use snapDOM
Installation
Install the core package with npm. Install the official plugin package only when the project needs its extra exporters or capture effects.
npm install @zumer/snapdom npm install @zumer/snapdom-plugins
Import the core package in an ES module:
import { snapdom } from '@zumer/snapdom';For direct browser use, load the distributed browser build:
<script src="https://unpkg.com/@zumer/snapdom@latest/dist/snapdom.js"></script>
An ES module build is also available from a CDN:
import { snapdom } from 'https://esm.sh/@zumer/snapdom@latest';Basic Usage
Use a shortcut when one output format is enough:
const card = document.querySelector('#profile-card');
const image = await snapdom.toPng(card);
document.body.appendChild(image);Capture once when several exports need the captured state:
const card = document.querySelector('#invoice-preview');
const result = await snapdom(card);
const png = await result.toPng();
const svg = await result.toSvg();
const canvas = await result.toCanvas();
const blob = await result.toBlob({ format: 'png' });
await result.download({
format: 'jpg',
filename: 'invoice-export'
});Capture an HTML String
snapdom.fromString() mounts the supplied markup offscreen before capture. Sanitize untrusted HTML first because inline handlers inside the markup execute in the page origin.
const result = await snapdom.fromString( '<article class="card">Hello</article>' ); const image = await result.toPng();
Output Methods
| Method | Result |
|---|---|
url | Contains the capture data URL for rendered captures. |
needs | Reports whether the capture ran through the clone or render stage. |
warnings | Contains recoverable capture and export diagnostics. |
meta | Exposes frozen capture geometry for rendered captures. |
toRaw() | Returns the capture data URL. |
to(type, options?) | Runs a core or plugin exporter by key. |
toSvg() | Returns an HTMLImageElement for the SVG capture. |
toCanvas() | Returns an HTMLCanvasElement. The export options can include a crop rectangle in capture coordinates. |
toBlob() | Returns a Blob. Export options include format, deprecated type, quality, width, and height. |
toPng() | Returns a PNG-backed HTMLImageElement. |
toJpg() / toJpeg() | Returns a JPEG-backed HTMLImageElement. |
toWebp() | Returns a WebP-backed HTMLImageElement. |
download() | Downloads the selected output. Export options include filename, format, deprecated type, quality, width, and height. |
toImg() | Deprecated alias. Use toSvg(). |
Static snapDOM Methods
snapdom(element, options?)returns a reusableCaptureResult.snapdom.toRaw(element, options?)captures an element and returns its data URL.snapdom.toImg(element, options?)is the deprecated static alias forsnapdom.toSvg().snapdom.toSvg(element, options?)captures an element as an SVG image element.snapdom.toCanvas(element, options?)captures an element to canvas.snapdom.toBlob(element, options?)captures an element as a Blob.snapdom.toPng(element, options?)captures an element as PNG.snapdom.toJpg(element, options?)captures an element as JPEG.snapdom.toWebp(element, options?)captures an element as WebP.snapdom.download(element, options?)captures and downloads an element.snapdom.fromString(html, options?)captures trusted or sanitized HTML markup.snapdom.preCapture()learns eligible click or press captures and prepares them on later hover or focus intent.snapdom.plugins(...plugins)registers global plugins.snapdom.versionexposes the package version.
Capture Options
width and height define absolute output dimensions. scale applies only when neither dimension is set. Raster pixel dimensions also use dpr.
scale(number, default1): Sets the output scale whenwidthandheightare unset.dpr(number, defaultdevicePixelRatio): Sets the device pixel ratio used for rasterization.width(number, unset): Sets the output width and preserves aspect ratio whenheightis unset.height(number, unset): Sets the output height and preserves aspect ratio whenwidthis unset.backgroundColor(string | null): Uses transparency by default, with white as the default background for JPEG and WebP.quality(number, default0.92): Sets JPEG and WebP quality from0to1.format(svg | png | jpg | jpeg | webp, defaultpng): Sets the default format for format-selecting exports.type: Deprecated alias forformat.useProxy(string, unset): Sets a proxy prefix used as a fallback when CORS blocks an asset request.exclude(string | predicate | array, unset): Excludes nodes by selector, predicate, or a mixed array of both.excludeMode(hide | remove, defaulthide): Keeps excluded layout space or removes the node from captured layout.filter((element) => boolean, unset): Keeps nodes for truthy returns and omits nodes for falsy returns.filterMode(hide | remove, defaulthide): Sets layout behavior for nodes rejected byfilter.reconcile(boolean, defaultfalse): Measures the styled clone against the source and corrects diverging boxes.invalidate(boolean, defaultfalse): Forces one fresh capture after changes that do not emit an observable DOM signal, such as programmatic CSSOM edits.outerTransforms(boolean, defaulttrue): Keeps root rotation when true. False removes root rotation while retaining scale and skew.outerShadows(boolean | "subtree", defaultfalse): Controls root shadow and outline bleed."subtree"can include descendant shadow ink outside the root box.clip("viewport" | { x, y, width, height } | null, defaultnull): Captures a viewport or page-coordinate region.embedFonts(boolean | "auto", default"auto"): Embeds web fonts used by the captured subtree. System-font captures skip the font pass in automatic mode.localFonts(LocalFont[], unset): Supplies font family and source descriptors directly.iconFonts(string | RegExp | array, unset): Extends icon-font family detection.excludeFonts(object, unset): Excludes non-icon fonts by family, domain, or subset.fontStylesheetDomains(string[], unset): Includes extra domains in cross-origin font stylesheet discovery.excludeStyleProps(RegExp | function, unset): Omits selected computed style properties during style capture.engine("svg" | "html-in-canvas", default"svg"): Selects the renderer. The native canvas engine is experimental and requires a compatible custom build.debug(boolean, defaultfalse): Writes capture diagnostics to the console.filename(string, default"snapDOM"): Sets the base filename used bydownload().fallbackURL(string | function, unset): Supplies a replacement URL when an image cannot be inlined.cache("soft" | "disabled" | false, default"soft"): Controls persistent resource and style caches.placeholders(boolean, defaulttrue): Displays placeholders for resources that cannot be captured.captureSelection(boolean, defaultfalse): Includes the current text selection in the capture.plugins(PluginUse[], unset): Attaches plugins to one capture.canvas(HTMLCanvasElement, unset): Reuses an existing canvas for canvas-based exports.
Node Attributes
| Attribute | Effect |
|---|---|
data-capture="exclude" | Excludes the node using the active exclusion mode. |
data-capture="placeholder" | Replaces the node with a placeholder. |
data-placeholder-text | Sets text shown in the placeholder. |
Cache and Repeated Captures
Result memoization and persistent resource caching are different systems. Eligible unchanged elements can reuse an earlier capture automatically. Canvas, video, iframe, recognized animation, and function-driven capture rules are refreshed when required.
cache: "soft" is the v3 default. Use cache: "disabled" or false for debugging when persistent resource and style caches must be cleared and bypassed. Legacy v2 values "auto" and "full" map to "soft" at runtime but are no longer part of the v3 public type.
Use invalidate: true for the next capture after changes such as sheet.insertRule() or cssRule.style.*, where the browser exposes no DOM mutation signal.
const image = await snapdom.toPng(document.querySelector('#preview'), {
invalidate: true
});Pre-Capture on User Intent
snapdom.preCapture() takes no arguments. It learns eligible captures started from a control press or click and prepares that capture on later hover or focus. It is not a direct replacement for the removed v2 preCache() API.
snapdom.preCapture();
button.addEventListener('click', async () => {
const image = await snapdom.toPng(document.querySelector('#card'));
document.body.appendChild(image);
});Official Plugins
html-exportexports captured HTML with styles and fonts.context-exportexports a text outline or JSON page context.agent-mapexports an image plus an element map with semantic and geometry data.pdf-imageexports a PDF that contains an image capture.gif-exportrecords changing content as GIF.video-exportrecords changing content through browser video encoding.ascii-exportexports an ASCII representation of the capture.filterapplies CSS filter effects to the captured clone.color-tintapplies a tint overlay.timestamp-overlayplaces a timestamp label on the captured clone.replace-textreplaces matching text inside the clone.redact-inputsmasks selected form values and private captured content.
Import plugin factories and call them with their configuration:
import { snapdom } from '@zumer/snapdom';
import { filter } from '@zumer/snapdom-plugins/filter';
import { timestampOverlay } from '@zumer/snapdom-plugins/timestamp-overlay';
const result = await snapdom(document.querySelector('#card'), {
plugins: [
filter({ preset: 'grayscale' }),
timestampOverlay({ position: 'top-right', format: 'date' })
]
});
const image = await result.toPng();Register a plugin globally when every later capture should use it:
const grayscale = filter({ preset: 'grayscale' });
snapdom.plugins(grayscale);Plugin API
A plugin object uses a unique name. needs can select the clone or render capture stage, and pure marks deterministic capture hooks as eligible for reuse.
beforeSnap(context)runs before capture processing.beforeClone(context)runs before the DOM subtree is cloned.afterClone(context)runs after cloning.resolveNode(node, context)can replace or skip an individual source node.beforeRender(context)runs before rendering.afterRender(context)runs after rendering.beforeExport(context, payload)runs before each export.afterExport(context, payload)observes each export result. Its return value is ignored.defineExports(context)defines custom export keys and result helpers.afterSnap(context)runs once after the first successful export.
Global plugin registry exports are registerPlugins(), clearPlugins(), getGlobalPlugins(), and normalizePlugin(). The package also exports STAGES, DEFAULT_STAGE, and assertNeeds() for plugin-stage handling.
A custom exporter belongs in defineExports(). afterExport() can inspect the finished result through its payload, but its return value does not replace the export.
function auditPlugin() {
return {
name: 'audit-logger',
afterClone(context) {
context.clone.setAttribute('data-captured', 'true');
},
afterExport(context, payload) {
console.log(payload.format, payload.result);
},
defineExports() {
return {
report: async (context, options) => {
return context.exports.png(options);
}
};
}
};
}
const result = await snapdom(document.querySelector('#report-widget'), {
plugins: [auditPlugin()]
});
const report = await result.toReport();Upgrading from snapDOM v2
| v2 behavior | v3 change |
|---|---|
| Web fonts were opt-in. | embedFonts: "auto" is now the default. |
scale could multiply explicit width or height. | width and height now take precedence over scale. |
burst opted into repeated-capture memoization. | Eligible capture reuse is automatic. Remove burst. |
preCache() prepared resources. | preCache() is removed. preCapture() is a different user-intent feature. |
fast selected an optimization mode. | fast is removed. |
cache accepted auto and full. | The public v3 values are soft, disabled, or false. Legacy auto and full map to soft at runtime. |
compress controlled embedded image downsampling. | Image optimization is automatic. Remove compress. |
resolvePicturePlaceholders and pictureResolver configured responsive image preparation. | Responsive and lazy image resolution runs automatically. Remove those public options. |
| Core redaction handled additional visible input values. | Core masks password fields. Use the redact-inputs plugin for other fields. |
afterExport return values could be used as hook payloads. | Hook return values are ignored. Use defineExports for custom outputs. |
html-in-canvas was exposed through a plugin subpath. | The plugin subpath is removed. The experimental renderer now uses engine: "html-in-canvas" in a compatible custom build. |
Best Practices & Performance
Repeated captures benefit from automatic memoization when the element and capture rules are eligible for reuse. Canvas, video, iframe, recognized animation, and function-valued capture rules run fresh when their current state must be read again.
- Use
clip: "viewport"or a rectangle when only part of a large element is needed. Offscreen subtrees outside the clip can be pruned before styling and inlining. - Use
invalidate: trueafter programmatic CSSOM changes such assheet.insertRule()that do not emit a DOM mutation signal. - Keep
cache: "soft"for normal use. Use"disabled"orfalsewhen persistent resource and style caches must be bypassed during debugging. - Keep cross-origin images and font resources readable by the browser. Configure
useProxywhen the project has a proxy that can return blocked assets. - Use explicit
widthorheightfor a fixed export size. In v3, those dimensions take precedence overscale. - Inspect
result.warningswhen an export uses a fallback or hits a browser canvas limit. - Keep the default SVG engine for normal builds.
engine: "html-in-canvas"is experimental and requires a compatible custom build.
The current v3 steady-state benchmark uses headless Chromium through Playwright, DPR 1, scale 1, Apple Silicon, and PNG data URLs as the common output. The values are medians of four runs with repeat-result memoization disabled.
| Library | Complex Card | 500-row Table |
|---|---|---|
| snapDOM | 10.0 ms | 130.1 ms |
| modern-screenshot 4.7.0 | 30.5 ms | 579.9 ms |
| html2canvas 1.4.1 | 82.5 ms | 365.0 ms |
| dom-to-image 2.6.0 | 154.9 ms | 1,041.5 ms |
Compared to Alternatives
DOM capture libraries differ in the browser features they reproduce. The current v3 capability fixture checks rendered output with pixel tests and uses each library’s default configuration.
| Library | Shadow DOM | Pseudo-elements | adoptedStyleSheets |
|---|---|---|---|
| snapDOM | ✅ | ✅ | ✅ |
| modern-screenshot 4.7.0 | ✅ | ✅ | ✅ |
| html2canvas 1.4.1 | ✅ | ✅ | ❌ |
| dom-to-image 2.6.0 | ❌ | ✅ | ✅ |
Alternatives & Related Resources
- DOM-to-PPTX: High-Fidelity HTML to PowerPoint Converter in JavaScript
- Generate Professional & Beautiful PDF Tables with jsPDF-Table
FAQs
Q: How do I disable snapDOM caching?
A: Use cache: "disabled" or cache: false when persistent resource and style caches must be cleared and bypassed for debugging. The default v3 policy is "soft". Legacy "auto" and "full" values map to "soft" at runtime.
Q: Can snapDOM capture iframe content?
A: Yes for same-origin iframe documents. Cross-origin iframe content cannot be read by the page and is represented by a placeholder or an invisible spacer.
Q: What replaces preCache() in snapDOM v3?
A: There is no direct replacement. preCache() was removed. snapdom.preCapture() learns eligible captures from press or click activity and prepares them on later hover or focus.
Q: Does scale override width and height?
A: No. In v3, explicit width or height takes precedence. scale applies only when neither dimension is set.
Q: What does snapdom() return?
A: snapdom(element, options) returns a Promise that resolves to a reusable CaptureResult. Use methods such as toPng(), toSvg(), toCanvas(), toBlob(), and download() on that result.
Changelog:
v3.3.0 (10/05/2026)
- feat: add editable vector export and enhance PDF capabilities
- feat(plugins): add open-source vector export
- feat: improve plugin export contracts
- feat: replace pdf-image with full PDF export
- bugfixes
v3.2.0 (09/29/2026)
- bugfixes
- feat: export PNG files beyond the canvas limit
- update crop option
v3.1.1 (09/25/2026)
- bugfixes
v3.1.0 (09/22/2026)
- feat(capture): bring back fast: false as a time-sliced capture
- feat(capture): meter, progress and slider part rules into the capture
- perf(styles): prune shadow-root style reads with a per-capture universe
- fix: restore ArcGIS table captures.
v3.0.0 (09/14/2026)
- Introduced automatic reuse for eligible unchanged captures and incremental recapture for safe local DOM changes.
- Changed web font embedding to
embedFonts: "auto"by default. - Added
snapdom.fromString()andsnapdom.preCapture(). - Changed output sizing so explicit
widthandheighttake precedence overscale. - Removed
preCache,fast,burst,compress,resolvePicturePlaceholders, andpictureResolverfrom the public v3 API. - Changed core redaction to password fields only. Other form values can be masked with the
redact-inputsplugin. - Updated
afterExporthooks so return values are ignored. Custom outputs usedefineExports. - Aligned the official plugin package with the v3 core.
v2.24.18 (09/11/2026)
- bugfixes
v2.24.17 (09/10/2026)
- bugfixes
v2.24.16 (09/08/2026)
- bugfixes
v2.24.15 (08/30/2026)
- bugfixes
v2.24.10 (08/25/2026)
- bugfixes
v2.24.7 (08/22/2026)
- bugfixes
v2.23.2 (08/04/2026)
- bugfixes
v2.23.1 (07/28/2026)
- bugfixes
v2.23.0 (07/27/2026)
- bugfixes
v2.22.0 (07/26/2026)
- lots of improvements.
v2.18.0 (07/22/2026)
- feat: emulate backdrop-filter at capture time
- feat: clip option + snapdom.viewport(): region capture with offscreen culling
- bugfixes
v2.16.0 (07/13/2026)
- Bugfixes
v2.15.0 (07/05/2026)
- Bugfixes
v2.12.9 (06/16/2026)
- Update
v2.12.8 (06/04/2026)
- Bugfixes
v2.12.2 (05/31/2026)
- Bugfixes
v2.12.1 (05/29/2026)
- Bugfixes
v2.12.0 (05/05/2026)
- Bugfixes
v2.9.0 (04/23/2026)
- Bugfixes
v2.8.0 (04/09/2026)
- Improve robustness of icon font detection
v2.7.0 (03/27/2026)
- feat(plugins): add multiple new SnapDOM plugins including ascii-export, color-tint, filter, html-in-canvas, pdf-image, picture-resolver, replace-text, timestamp-overlay. Each plugin enhances image processing and manipulation capabilities.
- feat(plugin-template): add initial SnapDOM plugin template with example usage and options.
v2.6.0 (03/23/2026)
- bugfixes
v2.5.0 (03/17/2026)
- fix: CSS vars perf, scrollbar styles, SVG image inline, nested line-clamp, iframe pseudos & isolation, Tailwind border.
- fix: enable image download on iOS via Web Share API.
- feat(scrollbar): implement custom scrollbar style collection for capture to ensure styles are applied correctly.
- feat(styles): normalize Tailwind border styles in capture and inlineAllStyles to ensure consistent output.
- feat(lineClamp): introduce lineClampTree function to apply line-clamp to nested elements, enhancing ellipsis rendering.
- test(styles): add tests for excluding CSS properties from snapshots to ensure fidelity with CSS variables.
- test(capture): add test for iframe CSS isolation to ensure wrapper div does not inherit iframe styles.
- refactor(capture): replace getComputedStyle with getStyle for improved iframe support and consistency across style retrieval.
- feat(pseudo): implement suppression of native ::before/::after pseudo-elements in cloned styles to prevent double rendering.
- fix(capture): update Safari padding logic to avoid edge clipping by applying padding only when necessary based on bounding box transforms.
- test(fonts): add test for cross-origin CSS support in embedCustomFonts function, verifying correct handling of custom CDN stylesheets.
- feat(fonts): add fontStylesheetDomains option to support cross-origin CSS fetching, enhancing font loading capabilities.
- feat(styles): add support for capturing -webkit-text-stroke properties in Safari to enhance style snapshot accuracy.
- fix(styles): normalize inline styles to ensure !important rules in stylesheets correctly override inline styles in clones.
- refactor: improve dimension handling in deepClone and createCheckboxRadioReplacement functions for better accuracy and consistency.
- refactor: enhance checkbox/radio replacement for Firefox with SVG implementation for consistent rendering and improved styling.
- fix(background): resolve relative URLs and fallback to background shorthand for url() when background-image is empty.
- fix: enable image download on iOS via Web Share API.
- feat(tests): add comprehensive test coverage for various modules including exporters, utils, and modules to improve overall code reliability.
- feat(debug): introduce debug option to log suppressed errors for troubleshooting, enhancing error visibility during capture processes.
- fix: Firefox checkbox radio replacement.
- refactor(cache): implement EvictingMap for cache management to limit memory usage and improve performance.
- refactor(styles): improve height handling for transparent wrappers to support margin collapsing and enhance layout stability.
- fix(styles): prevent overriding border styles when using border-image, and improve getStyle fallback handling.
- feat(images): add support for inlining SVG <image> elements as data URLs.
- feat(safari): implement font and image decode warmup for Safari to address WebKit Bug #219770, enhancing capture reliability.
- test(getStyle): add tests to ensure getStyle never returns undefined for elements and pseudo-elements.
- refactor(snapdom): streamline plugin exports by consolidating export functions into a loop for improved maintainability.
- feat(capture): enhance DOM capture dimensions for root elements by measuring scroll dimensions and using a temporary container for accurate height and width calculations.
- fix(css): enhance getWindowForElement and getStyle functions to handle cross-document scenarios and improve fallback logic.
- refactor(context): remove inline cache policy normalization and import from cache module for improved code organization.
- feat(safari): add safariWarmupAttempts option to optimize font and image decoding for improved capture performance.
- fix(styles): prevent width constraints on inline and specific tags to avoid text wrapping issues.
- docs: update README files to replace NPM version badge with weekly downloads badge.
- chore(.gitignore): add ‘demos/’ directory to .gitignore to exclude demo files from version control.
- refactor(prepare): simplify deepClone call by removing redundant element argument for cleaner code.
- fix(styles): adjust inline style for timestamp demo to prevent text wrapping.
- fix(snapdom): remove redundant safariWarmup reset to improve iteration logic.
- enable image download on iOS via Web Share API.
v2.1.0 (03/10/2026)
- fix: use nodeMap for source-clone alignment in inlinePseudoElements
- Update URL handling to use location.origin in fonts.js
- fix(background): inline background-image inside shadow DOM hosts
- feat: classify open issues by importance with priority labels and automated triage
- fix: CSS transform double scale bug
- fix: dynamic injected stylesheets with fonts
- Fix: Inherit root font-size in SVG output
v2.0.2 (01/28/2026)
- bugfix
v2.0.1 (11/26/2025)
- bugfix
v2.0.0 (11/19/2025)
- fix: improve CSS src property parsing in font faces
- Fix placeholder dimensions when image loading fails
v1.9.13 (10/05/2025)
- Adding ‘exclusionMode’ option
- Refactor: use BlobType alias consistently
- Improve CSS vars detection
- Fix toImg() dimensions when scale==1
- Enhance web fonts detection on deph relative paths
- Add two new options to control transforms and shadows on root element
- Add toSvg() in replacement of toImg()
- Improve relative path detection
v1.9.11 (09/10/2025)
- Fix Safari bug that prevents capture
v1.9.10 (08/14/2025)
- feat: fast configuration item to control deep recursion of deepClone
- Fix the issue when image loading fails and add a default image placeholder attribute
v1.9.9 (08/14/2025)
- Improves external fonts handling.
- Handles srcset.
- Fix speed regression.
- Handles Blob src.
v1.9.8 (08/09/2025)
- fix: invalid border-width check
- fix(types): update preCache
v1.9.7 (07/27/2025)
- Improve pseudo elements detection.
- Remove default backgroundColor on download().
- Bugfixes
v1.9.6 (07/20/2025)
- Add options argument to toBlob function
- Keep canvas CSS style
- Improve: handles local() source font
- Improve webcomponent clone
- Perf: unifies cache
- Improve cache handling
- Adjust cache reset
- Improve regex
- Add primitive support to css counter
- Fix bug background-color on export formats
- Fix regression textArea duplication
- Prevent process local ids
v1.9.5 (07/14/2025)
- copy checkbox.indeterminate
- update docs to show exclude and filter
- fix: add type def for SnapOptions
- dd slot detection and Fix textarea content duplication
v1.9.3 (07/10/2025)
- Add filter and exclude options for element exclusion.
- Missing width and height in types.
- fix: type check.
- Core update: Capture speed is drammatically increased.
- Core update: tries differents methods to fetch image, even proxy for CORS denied images. Important: crossOrigin is now inbuilt into fetchImages(), no longer needed as option.
- Improve fetchImage() by skiping svg format.
- Add iconFont options and fix doubled icon render.
- Add Layui icon font.
- Add Blob Types.
- Bug: fixes hidden last line PRE tag.
- Feat: handles external SVG defs.
- Prevents double url encoding.
- Fix scale background-image
v1.8.1 (06/30/2025)
- Add Lucide to icon font detection
- Fix: encode same uri multiple times
- Avoid background-image logic duplication
- Improve split multiple backgrounds
- Fix background image handling
- Feat: sanitize rootElement to avoid CSS layout conflicts
- Clean transform RootElement prop
- Fix: canvas style props
- Feat: handling @import and optimice cache
- Compile .js to es2015
- Improve inlinePseudoElements() to handle decorative properties
- Add ::first-letter detection
v1.7.0 (06/19/2025)
- add options.crossOrigin
- Improve inlineBackgroundImages to support multiple background-image values
v1.3.0 (06/14/2025)
- Fix: double scaled images
- Fix: background img & img base64 in pseudo elements
- Feat: captures input values
- Improve: Device Pixel Ratio handling
v1.2.5 (06/09/2025)
- Bugfixes
v1.2.2 (06/04/2025)
- Patch: type script definitions
v1.2.1 (05/31/2025)
- Feat(embedFonts): also embed icon fonts when embedFonts is true
- Fix expose snapdom and preCache on browser compilation
- Improve icon-font conversion
- Fix compress mode
v1.1.0 (05/28/2025)
- Add typescript declaration
- Feat. support scrolling state
- Fix bug by removing trim spaces
- Fix bug that prevents scale on png format
v1.0.0 (05/19/2025)
- Fix retina and scale bug
- Improve public API
- Fix bug to render canvas with precache compress mode
- Update to reflect new public API
- Add helper to check Safari
v0.9.9 (05/16/2025)
- Fix bug on collectUsedTagNames()
v0.9.8 (05/14/2025)
- Fix a bug in capture output format
v0.9.7 (05/14/2025)
- Add an option to switch between smooth and fast capture
- Improve detection of browsers default css styles
- Size of generated image is smaller in compress mode
- Enable embedding fonts
- Enable a pre caching for static assets (WIP)







