Where the bytes in an exported SVG go
Design tools write SVG for round-tripping, not for the web. An Inkscape file carries inkscape: and sodipodi: attributes, a <metadata> block and layer groups; Illustrator adds a generator comment and an XML declaration; most tools print coordinates as 4.000 and colours as #FFFFFF. None of that changes a single pixel. Optimising removes it and rewrites what remains in a shorter but equivalent form. Icons commonly lose half their size: the Inkscape icon in the first example drops from 578 to 256 bytes. For an icon inlined on every page of a site, or a sprite with hundreds of symbols, that adds up quickly. Serve the result with gzip or Brotli as well: shortened path data still compresses well, so the two savings stack.
What SVGO changes
This page runs SVGO’s default preset in multipass mode, repeating until a pass makes no further gains. In practice that means:
- The XML declaration, comments,
<metadata>, editor namespaces and attributes, and the redundantversionattribute are removed. - Groups that add nothing are flattened, and IDs that nothing references are deleted along with unused definitions in
<defs>. - Path data is rewritten with relative commands and implicit repeats:
M 20 34 L 28 42 L 44 24becomesm20 34 8 8 16-18. Simple shapes may be converted to a shorter<path>. - Numbers lose trailing zeros and excess precision, and colours take their shortest name or hex form:
#FFFFFFbecomes#fff,#FF0000becomesred. - Attribute order is normalised and default attribute values are dropped.
What is deliberately protected
Some SVGO defaults cause real breakage, so the configuration is adjusted. Referenced IDs are never renamed. Out of the box, SVGO shortens id="brandGradient" to id="a", which breaks CSS that targets #brandGradient, a <use href="sprite.svg#icon-cart"> in another file, or two inlined SVGs that both end up with an a. Here, any ID that is referenced through url(#...), href or xlink:href keeps its name and keeps working. The viewBox is always preserved, so the graphic still scales when you change width and height or set them in CSS. Width and height attributes are left as they are.
Safety checks wrap the optimiser on both sides. Before SVGO runs, the input is parsed with the XML parser, so a malformed file is rejected with a precise line and column rather than handed to the optimiser. Afterwards, the output is parsed again; if it is not well-formed SVG, the result is thrown away and you see an error instead of a corrupted file.
Security warnings
Optimising does not sanitise. A <script> element, an onclick or onload handler, a javascript: link or a <foreignObject> passes through SVGO and is reported as a warning so you can remove it before publishing user-supplied files. Optimisation happens in your browser; the SVG is never uploaded.
Ctrl/Cmd+Shift+M toggles between the optimised output and the indented view from the SVG formatter, and Ctrl/Cmd+Shift+C copies the result. The Preview tab renders the optimised file so you can confirm it looks identical.
Examples
Inkscape export with metadata and a layer group
Declaration, comment, metadata, editor attributes and the empty layer group all go, and the checkmark path is rewritten in relative form.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="64" height="64" viewBox="0 0 64 64" version="1.1">
<metadata>exported 2026-09-14</metadata>
<g inkscape:label="Layer 1" id="layer1">
<rect x="4.000" y="4.000" width="56.000" height="56.000" rx="12" fill="#FFFFFF" stroke="#000000" stroke-width="4"/>
<path d="M 20 34 L 28 42 L 44 24" fill="none" stroke="#16a34a" stroke-width="6"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><rect width="56" height="56" x="4" y="4" fill="#fff" stroke="#000" stroke-width="4" rx="12"/><path fill="none" stroke="#16a34a" stroke-width="6" d="m20 34 8 8 16-18"/></svg>Icon sprite whose IDs are referenced
brandGradient and dot keep their names because they are referenced, while the unused clip path is removed.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 40">
<defs>
<linearGradient id="brandGradient">
<stop offset="0" stop-color="#2563eb"/>
<stop offset="1" stop-color="#7c3aed"/>
</linearGradient>
<circle id="dot" r="6" fill="url(#brandGradient)"/>
<clipPath id="unusedClip"><rect width="10" height="10"/></clipPath>
</defs>
<use href="#dot" x="20" y="20"/>
<use xlink:href="#dot" x="50" y="20"/>
<use href="#dot" x="80" y="20"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 40"><defs><linearGradient id="brandGradient"><stop offset="0" stop-color="#2563eb"/><stop offset="1" stop-color="#7c3aed"/></linearGradient><circle id="dot" r="6" fill="url(#brandGradient)"/></defs><use x="20" y="20" href="#dot"/><use xlink:href="#dot" x="50" y="20"/><use x="80" y="20" href="#dot"/></svg>Triangle with an inline click handler
The path shrinks to m12 2 10 20H2Z and the fill becomes red, and a warning points out that the onclick handler is still there.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M 12.000 2.000 L 22.000 22.000 L 2.000 22.000 Z" fill="#FF0000" onclick="track()"/></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="red" d="m12 2 10 20H2Z" onclick="track()"/></svg>Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
Expected </g> to close <g> opened at line 1, found </svg>Explained | The file is not well-formed: a group was opened and never closed, so the optimiser is not run. | Close the group before </svg>. Open the file in the SVG formatter to see the nesting clearly. |
The root element is <html>, expected <svg> | A whole HTML document or snippet was pasted instead of the SVG element inside it. | Copy from the opening <svg> tag to the closing </svg> tag only. |
SVGO produced markup that is not well-formed SVG, so the result was discarded | The optimiser hit an edge case and produced invalid markup. The safety check caught it before it reached the output. | Keep the original file, or format it instead of minifying, and report the input if you can share it. |
Unescaped '&' — it must start an entity reference like & or &Explained | An ampersand in a title, text label or link inside the SVG is not escaped. | Replace it with & and optimise again. |
Frequently asked questions
Is this the same as SVGO or SVGOMG?
It runs SVGO, the optimiser behind SVGOMG, with the default preset and multipass. The one change is that referenced IDs are never renamed, and there are no per-plugin toggles.
Will optimising change how my SVG looks?
It should not. The default preset only applies transforms that keep rendering identical, and the Preview tab lets you check the result before copying it.
Why is the viewBox kept?
Without a viewBox an SVG cannot scale to a different width or height, which breaks responsive icons. It is always preserved here.
Does the optimiser remove scripts from SVG files?
No. Scripts, event handlers and javascript: links are kept and flagged with warnings. Remove them yourself, or sanitise uploads on the server.