Webpage Screenshotter
unlistedby cogscides
Capture webpage screenshots from note URLs and save them as vault attachments.
Webpage Screenshotter
Desktop-only Obsidian plugin that captures webpage screenshots with Playwright and saves them as vault attachments.
Core commands
Default command set:
Capture from URLRun capture preset
Optional command set:
Run preset: <preset name>(registered only whenRegister custom preset commandsis enabled)
Installation (development)
cd .obsidian/plugins/webpage-screenshotter
npm install
npx playwright install chromium
npm run build
Project structure
src/main.ts: plugin source entrypointsrc/styles.css: plugin styles sourcemain.js: build output loaded by Obsidian (ignored by git)styles.css: copied fromsrc/styles.cssduring buildscripts/sync-version.mjs: syncspackage.jsonversion intomanifest.jsonandversions.jsonscripts/prepare-release.mjs: version bump + sync + build
Release flow
Local release prep
# patch|minor|major|1.2.3
npm run release:prepare -- patch
This will:
- bump
package.jsonversion (without creating a git tag) - sync
manifest.jsonandversions.json - build
main.jsand copystyles.css
GitHub Actions
CI: lint + build on PR/push tomainPrepare Release: manual version bump + commit + tagRelease: onv*tags, builds and uploads plugin assets
Settings
General
Output folder: vault-relative target folder for screenshotsURL property key: frontmatter key used by active-note URL capturesRegister custom preset commands: toggles runtime registration of non-default preset commands
Capture defaults
Default full pageViewport width/Viewport heightWait ms/Timeout ms/Wait untilImage type/Image qualitySelector(optional element capture)Filename templateEmbed width enabled/Embed width
Default filename template:
screenshot_{{DATE:YYMMDDHHmm}}-{{VIEWPORT_WIDTH}}x{{VIEWPORT_HEIGHT}}
If extension is omitted, the plugin appends the selected image type extension.
Frontmatter mapping
Rules are evaluated only when enabled.
Default rules:
screenshot = {{IMAGE_WIKILINK}}(enabled)screenshotCaptured = {{DATE}}(disabled)
Command presets
Preset list behavior:
- sorted alphabetically by preset name
- edits are draft-based
Save presetssaves and refreshes command registrationCancel changesappears only when drafts differ from persisted settingsRestore missing default presetsis always available and opens a selector- restore selector supports per-preset restore and
Restore Allwhen multiple defaults are missing
Template tokens
Date-aware token:
{{DATE}}default format:YY-MM-DD{{DATE:<moment-format>}}e.g.{{DATE:YYMMDDHHmm}}
Direct substitution tokens:
{{URL}}{{NOTE_TITLE}},{{NOTE_PATH}}{{IMAGE_FILENAME}},{{IMAGE_BASENAME}},{{IMAGE_EXTENSION}},{{IMAGE_PATH}}{{IMAGE_WIKILINK}},{{IMAGE_EMBED}},{{EMBED_WIDTH}}{{FULL_PAGE}},{{VIEWPORT_WIDTH}},{{VIEWPORT_HEIGHT}}{{IMAGE_TYPE}},{{IMAGE_QUALITY}}{{WAIT_UNTIL}},{{WAIT_MS}},{{TIMEOUT_MS}},{{SELECTOR}}
Token UX in settings:
- grouped legend with descriptions/examples
- click token to copy
{{input autocomplete in template fields
Runtime behavior
api.capture()requires a URL (or a preset flow that collects URL)api.captureFromActiveNote()reads URL from the active note frontmatter using configured key- active-note capture throws when no markdown file is active or URL property is missing/empty
- when
pasteModeis enabled, paste targets the active markdown editor only - clipboard copy uses Electron APIs and is desktop-only
- output filename is sanitized and extension-normalized (
png|jpeg|jpg|webp)
API
const api = app.plugins.plugins['webpage-screenshotter'].api
const result = await api.capture(options?)
const result2 = await api.captureFromActiveNote(options?)
await api.runPreset(presetId, overrides?)
await api.applyFrontmatter(result, filePath?, rules?)
const text = api.renderTemplate(template, result, filePath?)
const presets = api.listPresets()
const settings = api.getSettings()
Capture result reference
capture(), captureFromActiveNote(), and runPreset() all resolve to:
ok: true- Always
truefor successful captures.
- Always
url: string- Final URL used for capture.
outputPath: string- Vault-relative path where image was written.
outputFileName: string- Basename including extension (for example
shot.png).
- Basename including extension (for example
outputBaseName: string- Basename without extension.
outputExtension: string- Extension without dot.
absoluteOutputPath: string- Absolute filesystem path (used for clipboard load).
wikilink: string- Obsidian wikilink to file (for example
[[shot.png]]).
- Obsidian wikilink to file (for example
embed: string- Obsidian embed (
![[shot.png]]or width form like![[shot.png|720]]).
- Obsidian embed (
capturedAtIso: string- ISO timestamp for capture completion.
activeFilePath: string | null- Active markdown file path when available, otherwise
null.
- Active markdown file path when available, otherwise
captureParams: object- Effective capture parameters after applying defaults + overrides.
- fields:
fullPage,viewportWidth,viewportHeight,waitForMs,timeoutMs,waitUntil,imageType,imageQuality,selector,embedWidthEnabled,embedWidth.
Notes for developers:
captureParamsreflects normalized values used for Playwright and template token rendering.embedandwikilinkare prebuilt helpers; you usually do not need to construct these manually.
Templater examples
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.