# Svg Export

> Finalize a rendered SVG for production: run SVGO optimization, add accessibility metadata (<title>, <desc>), verify viewBox sanity, and copy to a user-specified destination. Use when the user says "ship it", "optimize and export", "make it production-ready", "minify this SVG", "copy the final SVG to <path>", "export <slug> for the website", or asks for the byte-size after optimization. Always run after /svg-animate produces a passing verdict and before the SVG is committed or shared.

- Skill: `chanmeng666/svg-export` (Agent Skill)
- Install (CLI): `npx skillmds@latest add chanmeng666/svg-export`
- Raw SKILL.md: https://api.skillmd.com/api/skills/chanmeng666/svg-export/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: ChanMeng666 (https://skillmd.com/u/chanmeng666)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/chanmeng666/svg-export

---


You finalize an SVG that's already been rendered and visually verified.
You're the last step before the file leaves the repo. Your job: make it
small, accessible, and well-named.

## What was passed in

`$ARGUMENTS[0]` is the preset slug (must exist in `output/`).
`$ARGUMENTS[1..N]` may include `--out=<path>` to copy the final file
somewhere outside `output/`.

If no slug, return:

> usage: `/svg-export <preset-slug> [--out=<path>]`

If `output/<slug>.svg` doesn't exist, ask the caller to run
`/svg-animate` (or `node lib/render-cli.js <slug>`) first.

## Step 1 — Verify the source

Read `output/<slug>.svg`. Sanity-check:

- Contains `<svg ` opening tag and `</svg>` closing tag.
- Has a `viewBox` attribute (otherwise scaling is broken).
- Has a `<title>` element (presets emit it via composeSVG's `title` opt).
  If missing, fall back to the slug. Log a warning — presets should set
  title and desc explicitly.

If structural checks fail, return:

> EXPORT FAILED: <reason>
> Source: output/<slug>.svg
> Re-render via `/svg-animate` or `node lib/render-cli.js <slug>`.

## Step 2 — Optimize with SVGO

The repo ships an **animation-safe** `svgo.config.mjs` at its root, which SVGO
picks up automatically. Just point at input + output:

```bash
npx svgo -i output/<slug>.svg -o output/<slug>.min.svg
```

DO NOT pass `--enable`/`--disable` (those are SVGO v2; this repo runs v3, where
they're config-only) and DO NOT run stock `preset-default`. Stock SVGO is built
for static icons and **silently breaks animations**: it collapses the group
nesting that carries animation transforms (relocating `transform-box: fill-box`
origins — e.g. a blink's eyes jump to the corner), minifies `<style>` (dropping
`@keyframes`), and converts shape elements that are animation targets. The repo
config disables exactly those plugins while still compressing path data. See
`docs/embedding-animated-svg.md`.

Capture before/after sizes. Typical savings: 35–40% on an animated preset. If
savings are < 5%, the file is already small — that's fine, not a problem.

**Always re-verify the minified file animates** (Step 3) — a size win that
broke the motion is a regression, not an optimization.

## Step 3 — Verify minified file still composes AND animates

Parse check — the file must contain `<svg` and `</svg>` and be non-empty.
For an animated source, ALSO confirm the motion survived:

- The `<style>` block and every `@keyframes` still present (grep count matches
  the source). A 0 here means SVGO dropped the animation.
- If the source has `transform-box`, it's still there.
- Ideally, render the minified file as an `<img>` (see `svg-verify`'s `<img>`
  step) and confirm it still moves — not just that it parses.

If any check fails, abort and keep the unminified version as authoritative:

```
WARNING: SVGO altered the animation (e.g. @keyframes dropped / blink detached).
Keeping output/<slug>.svg as final. Check svgo.config.mjs is being applied.
```

## Step 4 — Copy to destination (if requested)

If `--out=<path>` was passed:

- If the path ends in `.svg`, copy `output/<slug>.min.svg` there.
- If the path is a directory, copy as `<dir>/<slug>.svg` (NOT `.min.svg`
  — users want a clean filename at the destination).
- Create parent directories if missing.
- Refuse to overwrite without explicit acknowledgement (`--force`).

## Step 5 — Report

```
EXPORTED: <slug>
Source:     output/<slug>.svg (<bytes> bytes)
Minified:   output/<slug>.min.svg (<bytes> bytes, <pct>% saved)
Destination: <path or "stayed in output/">
Accessibility: title="..." desc="..."
ViewBox:    "<viewBox>"
```

Keep it under 8 lines. The caller will share this with the user.

## Anti-patterns

- ❌ Stripping `viewBox`, `<title>`, or `<desc>`. They're tiny and critical
  for accessibility / responsive scaling. SVGO's default `removeViewBox`
  preset would strip viewBox; we disable it.
- ❌ Overwriting an existing destination file without a `--force` flag.
  Users have lost work to that.
- ❌ Running SVGO on a file we're not sure about. Always do Step 1's
  structural check first.
- ❌ Forgetting to copy to `--out=` when the user asked. The whole point
  of this skill is shipping the file to where they want it.

