Troubleshooting
The handful of issues people hit first.
"Cannot find module 'domotion'" or "ERR_MODULE_NOT_FOUND"
Domotion is ESM-only. Make sure your project is set up to load ESM modules:
- In
package.json, set"type": "module". - If you can't (e.g. you're inside a CommonJS project), run scripts with
tsx:npx tsx your-script.ts.
"browserType.launch: Executable doesn't exist..."
Playwright's Chromium binary isn't installed yet. Run:
npx playwright install chromium
On Linux servers, install the system libraries Chromium needs in addition:
npx playwright install --with-deps chromium
Captured text uses the wrong font / falls back
Two likely causes:
- The web font hasn't loaded yet. Add
await page.evaluate(() => document.fonts.ready)after yourpage.setContentorpage.goto. - Domotion can't find the font on disk. The bundled
mapping table is tuned for macOS system fonts. For other fonts the path
renderer falls back to native
<text>. Either author your demos in system fonts, or accept the cross-engine font differences. See Fonts & non-Latin scripts.
Captured text drifts left/right across long lines
This usually means the per-character xOffsets array on the
text segment is missing — most often because the segment's text was mutated
between capture and render. The renderer fell back to summing fontkit
advance widths, which accumulates ~0.5px of drift per character against
Chromium's sub-pixel positioning.
Fix: avoid mutating el.text after capture. If you need to
substitute text, also clear el.textSegments so the renderer
re-shapes from scratch with consistent metrics.
Animated SVG flickers between frames
Three possible causes, in order of likelihood:
- An overlay is preventing the merge fast path. Even one overlay anywhere in the sequence forces every frame onto the per-frame- atomic path, which can show a one-frame dark flash on transitions. Where you can express the overlaid content as a captured frame instead, it'll both look better and be smaller.
- You're using a non-crossfade transition.
push-leftandscrolluse different rendering; they don't flicker but they also can't merge. If you don't need the spatial transition, switching tocrossfadeusually fixes visual glitches and shrinks the file. - Two frames defined the same SVG ID. Always pass a unique
idPrefixper frame toelementTreeToSvg— without it, clip-path / gradient / glyph IDs collide and the wrong shapes get referenced.
Output SVG is huge (> 200 KB)
Three quick wins:
- Run
optimizeSvg(svg)if you haven't. - Crop to the visible region — capture the smallest viewport that contains the demo content.
- Cut frames. Each animation frame is one capture's worth of glyph outlines; aim for 3–5 frames maximum.
See Optimize output size for the full toolkit.
Captured page is missing dynamic content
You captured before the content was rendered. Common pre-capture waits:
// Wait for a known element to appear
await page.waitForSelector(".product-list .item");
// Wait for fonts
await page.evaluate(() => document.fonts.ready);
// Wait for network to settle
await page.goto(url, { waitUntil: "networkidle" });
// Wait for an app-specific signal
await page.waitForFunction(() => window.__appReady === true);
Captured page has running animations frozen at random frames
Pause CSS animations and transitions before capturing so the result is reproducible:
await page.addStyleTag({
content: `*, *::before, *::after {
animation-play-state: paused !important;
transition: none !important;
}`,
});
Some elements render as solid rectangles
Likely because the element uses a feature Domotion can't reproduce in
SVG: backdrop-filter, conic gradient, complex
clip-path: path(...). Check the capture warnings:
import { logCaptureWarnings } from "domotion";
logCaptureWarnings();
Each warning identifies the offending selector and feature. See the CSS support overview for the current matrix.
Filing a bug
If you've hit something that isn't on this page or in the FAQ:
- Run with capture warnings enabled and include the output.
- Include the input HTML and the produced SVG in the report.
- Note the Node version, Playwright version, and OS.
- If you can, include a Chromium screenshot of the same content (so the expected vs. actual is unambiguous).