# Troubleshooting Exporting Diagrams to PNG with Playwright: A Complete Guide

> Troubleshoot exporting diagrams to PNG with Playwright. Learn how to fix common issues with installation, fonts, and scale factors for crisp, accurate images. Get the complete guide.

- Repository: [Cathryn Lavery/diagram-design](https://github.com/cathrynlavery/diagram-design)
- Tags: how-to-guide
- Published: 2026-09-09

---

**Exporting diagrams to PNG requires Playwright and Chromium to be properly installed, the source HTML to include Google Fonts links, and a valid device scale factor between 1 and 4 to render crisp, accurate images.**

The `cathrynlavery/diagram-design` repository uses Playwright to rasterize SVG diagrams into high-fidelity PNG images. This process, defined in [`skills/diagram-design/references/export.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/export.md) and validated by [`scripts/verify-doctor.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-doctor.py), involves six distinct architectural steps that can fail if dependencies are missing or the source HTML lacks required font declarations.

## How PNG Export Works in diagram-design

The export workflow is a two-step rasterization process that renders the original HTML (not just the SVG) to preserve external fonts and CSS effects. Below is the complete execution path.

### Step 1: Detect Playwright Installation

Before any rasterization begins, the system verifies Playwright is importable. In [`skills/diagram-design/references/export.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/export.md) (lines 71-79), the detection logic attempts `import playwright` and aborts with explicit install instructions if the module is missing.

```python

# Detect Playwright – abort if not importable

try:
    import playwright  # noqa: F401

except ImportError:
    print(
        "Playwright isn't installed. To enable PNG export, run:\n"
        "pip install playwright\n"
        "playwright install chromium\n"
        "Then ask me to export again."
    )
    sys.exit(1)

```

### Step 2: Verify Chromium Binary

Even with Playwright installed, the Chromium browser binary must be present. The [`scripts/verify-doctor.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-doctor.py) script (lines 152-163 and 183-192) probes the binary path to ensure `playwright install chromium` has been executed successfully.

### Step 3: Prepare HTML with Font Links

The rasterizer loads the original HTML file rather than extracted SVG markup to ensure `<link href="...fonts.googleapis.com...">` tags are honored. Missing font links cause the screenshot to fall back to system fonts, producing text that appears blurry or incorrectly styled.

### Step 4: Launch Playwright and Screenshot

A temporary Python script launches Chromium with a configurable `device_scale_factor` (default 2) and captures the SVG element. As implemented in [`export.md`](https://github.com/cathrynlavery/diagram-design/blob/main/export.md) (lines 90-106), the rasterization uses `page.locator("svg").first.screenshot()` with `omit_background=True` for transparency support.

```python

# rasterise.py – invoked by the export skill

from playwright.sync_api import sync_playwright
import sys, pathlib

src, out = sys.argv[1], sys.argv[2]
scale = int(sys.argv[3]) if len(sys.argv) > 3 else 2

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page(device_scale_factor=scale)
    page.goto(f"file://{pathlib.Path(src).resolve()}")
    page.wait_for_load_state("networkidle")
    page.locator("svg").first.screenshot(path=out, omit_background=True)
    browser.close()

```

### Step 5: Compute Output Dimensions

Final PNG dimensions equal `viewBox × device_scale_factor`. According to [`export.md`](https://github.com/cathrynlavery/diagram-design/blob/main/export.md) (lines 125-137), if you need exact pixel dimensions, calculate the scale as `target_width / viewBox_width`. The system rejects scales below 1 or above 4 to prevent quality loss.

```python

# Example: target width 1200px, viewBox width 960px

target_width = 1200
viewbox_width = 960
scale = target_width / viewbox_width   # → 1.25 (allowed)

```

### Step 6: Handle Edge Cases

The export logic includes specific guardrails defined in [`export.md`](https://github.com/cathrynlavery/diagram-design/blob/main/export.md) (lines 140-145):
- **Gallery HTML with multiple SVGs**: Aborts to prevent ambiguous selection
- **No `<svg>` element found**: Aborts with clear error
- **Full-page screenshot requests**: Redirects to browser-based capture methods

## Common Errors and Solutions

### "Playwright isn't installed" Error

**Symptom**: Export aborts immediately with installation instructions.

**Fix**: Run the exact commands shown in the error output:

```bash
pip install playwright
playwright install chromium

```

Verify installation using the doctor script: `python scripts/verify-doctor.py`.

### Chromium Binary Not Found

**Symptom**: The doctor script reports "Playwright is installed but Chromium is not ready" (lines 183-192 in [`verify-doctor.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-doctor.py)).

**Fix**: Re-run `playwright install chromium` and verify the binary exists at the expected cache location (e.g., `~/.cache/ms-playwright/chromium-<version>/chrome`).

### Wrong Fonts or Blurry Text

**Symptom**: PNG text appears different from browser preview.

**Cause**: Source HTML missing Google Fonts `<link>` tags in the `<head>` section.

**Fix**: Ensure the diagram generation injects font links or `@import` statements before export. The rasterizer requires these to be present in the HTML source, not just the SVG.

### Low Resolution Output

**Symptom**: Image appears pixelated or smaller than expected.

**Cause**: `device_scale_factor` set to 1 or an invalid custom scale.

**Fix**: Use the default scale of 2 for retina-quality output, or specify a custom scale between 1 and 4 as the third argument to the export command. Values above 4 are rejected to prevent excessive memory usage.

### Gallery Page Export Failures

**Symptom**: Export refuses to run on HTML files containing multiple SVG elements.

**Fix**: Export individual diagram files only. The tool intentionally refuses to guess which SVG to capture when multiple exist in the DOM.

## Summary

- **Dependency check**: The system verifies Playwright installation via `import playwright` and Chromium availability via [`verify-doctor.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-doctor.py) before attempting rasterization.
- **Font preservation**: Loading the full HTML (not just SVG) ensures Google Fonts render correctly; missing links cause font substitution.
- **Scale limits**: Valid scale factors range from 1 to 4, computed as `target_width / viewBox_width` for exact pixel dimensions.
- **Single SVG requirement**: The screenshot logic targets `page.locator("svg").first`, requiring exactly one SVG element per HTML file.
- **Source authority**: All behavior is documented in [`skills/diagram-design/references/export.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/export.md) with validation logic in [`scripts/verify-doctor.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-doctor.py).

## Frequently Asked Questions

### Why does the PNG look different from the SVG?

Playwright renders the complete HTML environment including external CSS and fonts, while static SVG viewers may ignore remote resources. According to the source code in [`export.md`](https://github.com/cathrynlavery/diagram-design/blob/main/export.md), if the HTML lacks `<link href="...fonts.googleapis.com...">` tags, the screenshot uses system fonts instead of the intended typefaces, causing visual discrepancies.

### What scale factor should I use for high-resolution exports?

Use the default `device_scale_factor` of 2 for standard high-resolution output suitable for presentations and documentation. For print materials requiring specific pixel dimensions, calculate the exact scale as `target_width / viewBox_width` (capped at 4) and pass it as the third argument to the export command.

### Can I export multiple diagrams at once from a gallery page?

No. The export logic in [`export.md`](https://github.com/cathrynlavery/diagram-design/blob/main/export.md) (lines 140-145) explicitly aborts when multiple SVG elements are detected to prevent ambiguous capture. You must export individual diagram files one at a time, or use browser-based full-page capture methods for gallery views.

### How do I verify my Playwright setup before attempting export?

Run `python scripts/verify-doctor.py` to execute the full health check. This script validates both the Python package import (lines 152-163) and the Chromium binary path (lines 183-192), displaying the same install commands that [`export.md`](https://github.com/cathrynlavery/diagram-design/blob/main/export.md) references if either component is missing.