
Security News
RubyGems Adds Cooldown Feature to Bundler for Newly Published Gems
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.
@zumer/snapdom-plugins
Advanced tools
Official plugins for SnapDOM — extend and transform DOM captures with zero core changes.
npm install @zumer/snapdom-plugins
Import plugins individually (recommended for tree-shaking):
import { snapdom } from '@zumer/snapdom';
import { filter } from '@zumer/snapdom-plugins/filter';
import { timestampOverlay } from '@zumer/snapdom-plugins/timestamp-overlay';
const result = await snapdom(element, {
plugins: [filter({ preset: 'grayscale' }), timestampOverlay()]
});
const png = await result.toPng();
Or import everything at once:
import { filter, timestampOverlay, replaceText } from '@zumer/snapdom-plugins';
CDN (no install):
import { snapdom } from 'https://esm.sh/@zumer/snapdom';
import { filter } from 'https://esm.sh/@zumer/snapdom-plugins/filter';
filterApplies CSS filter effects to the captured clone.
import { filter } from '@zumer/snapdom-plugins/filter';
snapdom(el, { plugins: [filter({ preset: 'grayscale' })] });
| Option | Type | Default | Description |
|---|---|---|---|
preset | string | — | 'grayscale' | 'sepia' | 'blur' | 'invert' | 'vintage' | 'dramatic' |
filter | string | '' | Raw CSS filter string, e.g. 'blur(2px) contrast(1.2)' |
timestamp-overlayAdds a translucent timestamp label to the captured clone.
import { timestampOverlay } from '@zumer/snapdom-plugins/timestamp-overlay';
snapdom(el, { plugins: [timestampOverlay({ position: 'top-right', format: 'date' })] });
| Option | Type | Default | Description |
|---|---|---|---|
format | string | function | 'datetime' | 'datetime' | 'date' | 'time' | 'iso' | custom (Date) => string |
position | string | 'bottom-right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' |
background | string | 'rgba(0,0,0,0.6)' | Label background color |
color | string | '#fff' | Label text color |
fontSize | number | 11 | Font size in px |
replace-textFind-and-replace text in the captured clone. Supports strings and regex.
import { replaceText } from '@zumer/snapdom-plugins/replace-text';
snapdom(el, {
plugins: [replaceText({
replacements: [
{ find: 'DRAFT', replace: 'APPROVED' },
{ find: /\d{4}-\d{2}-\d{2}/, replace: '[REDACTED]' }
]
})]
});
| Option | Type | Default | Description |
|---|---|---|---|
replacements | Array<{ find: string|RegExp, replace: string }> | [] | List of find/replace pairs |
color-tintTints the entire capture to a specified color using a mix-blend-mode overlay.
import { colorTint } from '@zumer/snapdom-plugins/color-tint';
snapdom(el, { plugins: [colorTint({ color: 'royalblue', opacity: 0.4 })] });
| Option | Type | Default | Description |
|---|---|---|---|
color | string | 'red' | Any CSS color value |
opacity | number | 1 | Overlay opacity (0–1) |
ascii-exportAdds a toAscii() export method that converts captures to ASCII art.
import { asciiExport } from '@zumer/snapdom-plugins/ascii-export';
const result = await snapdom(el, { plugins: [asciiExport({ width: 100 })] });
const art = await result.toAscii();
console.log(art);
| Option | Type | Default | Description |
|---|---|---|---|
width | number | 80 | Character width of output |
charset | string | ' .:-=+*#%@' | Characters from lightest to darkest |
invert | boolean | false | Invert luminance mapping |
pdf-imageExports the capture as a PNG embedded in a downloadable PDF (A4). Adds a toPdfImage() method.
import { pdfImage } from '@zumer/snapdom-plugins/pdf-image';
const result = await snapdom(el, { plugins: [pdfImage({ orientation: 'landscape' })] });
await result.toPdfImage(); // triggers download
| Option | Type | Default | Description |
|---|---|---|---|
orientation | string | 'portrait' | 'portrait' | 'landscape' |
quality | number | 0.92 | JPEG quality (0–1) |
filename | string | 'capture.pdf' | Download filename |
html-in-canvasUses the experimental WICG drawElementImage API for direct DOM-to-canvas rendering where supported. Falls back gracefully.
import { htmlInCanvas } from '@zumer/snapdom-plugins/html-in-canvas';
snapdom(el, { plugins: [htmlInCanvas()] });
This plugin uses an experimental browser API and may not work in all environments.
prompt-exportAdds a toPrompt() export method that returns an LLM-ready package: a structured element map with bounding boxes, a pre-formatted prompt text, and (optionally) an annotated screenshot. Tuned for vision-language models, browser-agent pipelines, visual QA, and any workflow that pairs a capture with structured metadata.
import { promptExport } from '@zumer/snapdom-plugins/prompt-export';
const result = await snapdom(el, { plugins: [promptExport()] });
// Default: no image, just the structured map + prompt text (cheapest)
const { elements, prompt, dimensions } = await result.toPrompt();
To also include the annotated image (for tasks that truly depend on vision):
const result = await snapdom(el, {
plugins: [promptExport({ include: ['image', 'elements', 'prompt'] })]
});
const { image, elements, prompt, dimensions } = await result.toPrompt();
The returned object (fields present only if requested via include):
| Field | Type | Description |
|---|---|---|
elements | Array | One entry per detected element: { id, tag, type, name, text, bbox, attributes, state?, styles?, covered? } |
prompt | string | Pre-formatted text describing interactive + semantic elements |
image | string | Data URL of the (optionally annotated) screenshot — only when include contains 'image' |
dimensions | {width, height} | Scaled dimensions (always present) |
elements is split into two types:
'interactive' — buttons, links, inputs, [role]/[tabindex] targets. These get numbered badges overlaid on the screenshot when annotate is on.'semantic' — headings, paragraphs, <nav>, <main>, images with alt, table cells, etc. Structural context, not overlaid.Each bbox is in pixel coordinates of the returned image (scaled against maxImageWidth).
Each interactive entry also carries:
name — the computed accessible name (aria-label → labelledby → alt → title → labels[0] → textContent)state — runtime state: { checked, disabled, focus, open, value, selectedText } (only keys that apply)styles — visually-meaningful computed props filtered to drop defaultscovered: true when another element is painted on top of the bbox center (an agent won't click through a modal)// Example — feed a vision-capable LLM
const { image, elements } = await result.toPrompt({
include: ['image', 'elements', 'prompt']
});
// image is a data URL → pass as image input
// elements is JSON → pass as structured context alongside the image
// "Click element [3]" → look up elements[3].bbox for real coordinates
| Option | Type | Default | Description |
|---|---|---|---|
include | string[] | ['elements', 'prompt'] | Fields to return. Add 'image' for tasks that need vision (chart content, layout QA, canvas). Use ['prompt'] for the cheapest text-only mode. |
annotate | boolean | true | Overlay numbered badges on interactive elements (only affects the image when included) |
promptMode | 'compact' | 'verbose' | 'compact' | Prompt text verbosity. Compact omits coords when badges are on the image. |
includeCoords | boolean | true | Include bbox in the prompt text |
imageFormat | 'png' | 'jpg' | 'webp' | 'png' | Output image format (only used when image is included) |
imageQuality | number | 0.8 | Quality for lossy formats (0–1) |
maxImageWidth | number | 1024 | Max width in px; downscales and rescales bboxes if larger |
interactiveSelector | string | see below | CSS selector for the interactive element set |
semanticSelector | string | see below | CSS selector for the semantic element set |
labelStyle | object | {} | Override styles for the numbered badges (position, color, backgroundColor, etc.) |
Defaults:
a[href], button, input, select, textarea, [role="button"|"link"|"tab"|"menuitem"|"checkbox"|"radio"], [tabindex]:not([tabindex="-1"]), summary, [contenteditable="true"]h1–h6, p, li, img[alt], nav, main, article, section, header, footer, label, td, th, figcaption, blockquote, legendBoth per-call options (opts.include, opts.imageFormat, etc.) and constructor options are supported; per-call wins.
The image is the most expensive part of toPrompt() to produce (canvas draw + data-URL serialization), so the default skips it. Add 'image' to include when the task actually uses vision:
// Vision-dependent task (chart content, layout QA, visual diff)
await result.toPrompt({ include: ['image', 'elements', 'prompt'] });
// Pure structured agent loop (cheapest)
await result.toPrompt({ include: ['prompt'] });
Global (applies to all captures):
import { snapdom } from '@zumer/snapdom';
import { filter } from '@zumer/snapdom-plugins/filter';
snapdom.plugins(filter({ preset: 'sepia' }));
Per-capture (overrides global for that call):
const result = await snapdom(element, {
plugins: [filter({ preset: 'dramatic' })]
});
Per-capture plugins run before global ones. Duplicate plugin names are skipped automatically.
Use the template to scaffold a new plugin in seconds:
npx degit zumerlab/snapdom/packages/plugin-template my-plugin
See PLUGIN_SPEC.md for the full hook specification and CONTRIBUTING_PLUGINS.md to get your plugin listed on the community page.
MIT
FAQs
Official plugins for SnapDOM
The npm package @zumer/snapdom-plugins receives a total of 121 weekly downloads. As such, @zumer/snapdom-plugins popularity was classified as not popular.
We found that @zumer/snapdom-plugins demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.

Security News
Federal audit finds NIST lacked a plan to clear the NVD backlog, wasted funds on duplicate work, and delayed use of CISA data.