IcoMoon Icons logo

IcoMoon SVG sprites: export, anatomy and the <use> element

You do not have to generate a font at all. The same selection you would feed the font generator can leave the IcoMoon app as a single SVG sprite: select your icons, open the Generate SVG & More tab, hit Download, and the zip contains symbol-defs.svg — one file where every icon is a reusable <symbol>. Any page that inlines or links that file can render any icon with a three-line <use> snippet. Below: what the export actually contains, how the sprite is structured, the browser caveats, and an honest answer to the sprite-or-font question.

Exporting SVG from the app instead of a font

In the app, build your selection exactly as you would for a font — the app tutorial covers importing and selecting. Then, instead of Generate Font, switch to the Generate SVG & More tab in the bottom bar. The Preferences dialog on that screen controls the icon- id prefix and lets you toggle extras like PNG renders. Download gives you a zip whose two files matter here: symbol-defs.svg (the sprite) and demo.html (open it to verify every symbol before you touch your codebase). Keep selection.json from the same zip — re-importing it later restores names and settings, so you can regenerate the sprite or even switch to a font export from the identical selection.

Anatomy of symbol-defs.svg

The sprite is nothing exotic — a hidden outer <svg> wrapping a <defs> block of symbols:

<svg aria-hidden="true"
     style="position:absolute; width:0; height:0; overflow:hidden">
  <defs>
    <symbol id="icon-home" viewBox="0 0 32 32">
      <path d="M32 19 16 6 0 19v-5L16 1l16 13z"/>
      <path d="M28 18v13h-8v-9h-8v9H4V18l12-10z"/>
    </symbol>
    <symbol id="icon-pencil" viewBox="0 0 32 32">
      <path d="M27 0a5 5 0 0 1 4 8l-2 2-7-7 2-2a5 5 0 0 1 3-1z"/>
    </symbol>
    <!-- one <symbol> per icon you selected -->
  </defs>
</svg>

Three details are load-bearing. First, each <symbol> carries its own viewBox, so icons scale independently no matter what size box you draw them into. Second, symbols render nothing by themselves — that is what makes the file safe to inline at the top of <body> without visual side effects. Third, the id attribute is the entire public API: rename ids in the app before exporting, because every consumer references them literally. The paths for the free set are the same ones published in the IcoMoon-Free repository (© Keyamoon, GPL / CC BY 4.0).

Rendering icons with <use>

There are two reference styles, and the difference matters more than it looks:

<!-- A: sprite inlined at the top of <body> — reference by id -->
<svg class="icon" width="24" height="24" aria-hidden="true" focusable="false">
  <use href="#icon-home"></use>
</svg>

<!-- B: sprite kept as a file — same-origin only -->
<svg class="icon" width="24" height="24" role="img" aria-label="Home">
  <use href="symbol-defs.svg#icon-home"></use>
</svg>

Variant A (inlined sprite, fragment-only reference) is the bulletproof option: no extra request, no origin rules, works in every browser that renders SVG. Variant B keeps your HTML clean and lets the sprite cache across pages. Either way, size and color come from ordinary CSS:

.icon {
  width: 1em;                /* scales with surrounding text */
  height: 1em;
  fill: currentColor;        /* inherits the text color */
  vertical-align: -0.125em;  /* optical baseline alignment */
}

Cross-browser notes

The big one: <use> will not load external references across origins — pointing it at a sprite on a different domain or CDN fails silently, with no console error in most browsers. Serve the file same-origin or inline it. IE 11 does not support external references at all; if you still support it, the svg4everybody polyfill rewrites variant B into inline content. And while the modern href attribute works in all evergreen browsers, WebKit builds from before roughly 2018 only understood xlink:href — adding both attributes is a harmless belt-and-braces move if your analytics show old Safari traffic.

Icon font vs SVG sprite: the honest comparison

Both exports come from the same selection, so this is purely a delivery-format decision:

Criterion Icon font SVG sprite
Color One color per icon, set via CSS color Multicolor paths preserved; currentColor still works for single-tone
Rendering Drawn as text — font smoothing can blur glyphs at odd sizes True vector rendering, crisp at every size
Accessibility Private Use Area characters are meaningless to screen readers; needs aria-hidden plus hidden text Plain markup: role and aria-label go straight on the svg element
Payload All 491 free glyphs travel together — 49 KB as WOFF2 Only the symbols you exported ship; unused icons never leave the app
Failure mode A 404 on the font file means blank squares everywhere A missing symbol renders empty but keeps its layout box
Legacy browsers Works wherever @font-face works, including old IE External references need the svg4everybody polyfill in IE 11
Markup weight One short CSS class per icon Three to four lines of SVG per placement

Which one should you pick?

For a new project in 2026, default to the sprite: better accessibility, sharper rendering, multicolor support, and you ship only the symbols you use instead of the whole set. Pick the font when you are feeding an existing pipeline built on icon classes, when the terser markup genuinely matters, or when legacy browser support is non-negotiable — the pseudo-element techniques in our CSS guide only apply to the font route. Because selection.json round-trips through the app, the choice is reversible in minutes, not a rewrite. If you just want the complete free set without running the generator, the download page has every format pre-built, and the official documentation covers the generator's remaining export options.

Sprites reward icons that were drawn as real vectors. The Ultimate pack — $59 one-time, 1,500+ icons — ships the original SVG sources, so everything on this page applies to it unchanged; the pricing breakdown compares it against the subscriptions.