SVGFlow
Open editor

SVG Sprite Builder

Merge several SVG icons into one sprite of <symbol> definitions, referenced with <use>. One request, one cache entry, and every icon still styleable from CSS.

Runs entirely in your browser — nothing is uploaded, no account needed.

Icons
Drop several SVGs at once
Each becomes a <symbol> with the file name as its id.
Sprite
Add icons to build the sprite.
Symbols0
Usage
Add icons to see the markup.

How the sprite is built

Drop any number of SVG files — or add the document already open in the editor — and each becomes a <symbol> in a single sprite document. Every symbol keeps the source file's own viewBox, or gets one synthesised from the file's width and height when it is missing, so icons drawn on different grids coexist and each scales on its own terms. The file's child elements are copied across as they are; <title>, <desc> and <metadata> are dropped, because labelling belongs at the point of use, not in a definition stamped onto every page. Ids default to the file names, slugified to safe characters, and are editable inline — they are the fragment your pages will reference. Assembly happens in your browser; nothing is uploaded.

Two outputs are produced together: the sprite itself — one hidden <svg> of symbol definitions — and a usage snippet with a ready <use href="#id"> line for every icon, marked aria-hidden for the common decorative case.

What <symbol> and <use> actually do

A <symbol> never renders on its own — it is a definition, parsed once and drawn zero times until something points at it. Each <use> stamps a live copy of the definition into the referencing <svg> as shadow content: the geometry is not duplicated in your markup, but it renders as if it were. Because the symbol carries its own viewBox, that copy scales to whatever size the referencing element is given — set width and height, or CSS, on the outer <svg class="icon"> and the icon fits itself. The economics follow: one definition, one parse, and every further appearance of the icon costs a one-line element instead of another copy of its paths.

Styling across the shadow boundary

The copy that <use> renders lives in a shadow tree, and CSS selectors do not match inside it — a rule targeting a path inside the icon never applies. What does cross the boundary is inheritance: color, and therefore currentColor, flows from the referencing element into the symbol's content, as do fill and stroke themselves wherever the shapes inside declare neither. That is the model to design for — run the icons through the Color Editor's currentColor conversion before building the sprite, style the outer <svg>, and reserve CSS custom properties for a deliberate second tone, since properties inherit through the boundary too. The colour guide walks through both patterns.

When a sprite is the right shape

The same icons appearing many times across a page or a server-rendered site: one definition, parsed once, referenced everywhere, with no per-icon weight beyond the <use> line. Sharing an icon set across pages that do not share a JavaScript bundle. Keeping templates readable — a one-line reference instead of forty lines of paths per icon. A sprite pairs with, rather than replaces, components: the practical split is components for the handful of icons in an app shell and a sprite for the long tail, as argued in the React guide. For one or two images that belong to a stylesheet rather than the markup, a data URI is the lighter tool.

Accessible icons from a sprite

The generated snippet marks each icon aria-hidden="true", which is right for the majority case: an icon sitting next to its own text label is decoration, and hiding it stops screen readers announcing everything twice. When the icon is the only content — an icon-only button — the accessible name goes on the button or on the referencing <svg> via aria-label, not into the sprite; that is why per-file <title> elements are stripped rather than carried into every stamped copy. The accessible icons guide covers both patterns.

Common problems

  • Icons don't render at all. The sprite is being referenced through <img> or from another origin. <use> needs the sprite inline in the same document — paste it at the top of <body>.
  • Gradients or filters inside the sprite stopped working. The sprite ships hidden with display:none, which is fine for plain shapes but has historically taken gradient and filter definitions down with it in some browsers. If your icons use them, hide the sprite with width="0" height="0" and absolute positioning instead.
  • Outline icons came out as solid shapes. Icon sets like Feather put fill="none" stroke="currentColor" on the root <svg>, and only the file's children are copied into the symbol — root attributes are not. Declare them on the referencing element instead: <svg class="icon" fill="none" stroke="currentColor" stroke-width="2"> — they inherit into the shadow content, which is where those sets expect them anyway.
  • Two icons render the same. Ids come from file names, so two files both named icon.svg collide — and ids are global to the page, so two sprites can collide with each other. The first definition in document order wins silently. Rename in the list, and prefix ids per sprite if you ship more than one.
  • CSS won't reach the shapes inside an icon. Selectors stop at the shadow boundary. Style the outer <svg> and design multi-part icons around inheritance and custom properties, as above.

Questions

Is this SVG sprite generator free?

Yes. Building sprites is free, with no account, no watermark and no limit on icons or exports. The site is funded by advertising.

What is an SVG sprite?

One SVG document holding many icons as <symbol> definitions. The symbols never render on their own; each page shows an icon with a one-line <use href="#id"> reference. One parse, one set of definitions, any number of appearances.

How do I use the sprite on my page?

Paste the sprite at the top of <body>, then place <svg class="icon"><use href="#icon-id" /></svg> wherever an icon should appear — the tool generates this snippet for every icon. Size the outer svg with CSS or width/height attributes.

Why don’t my icons show up?

Almost always because the sprite is not inline: <use> cannot reach into a file loaded through <img>, and a cross-origin sprite is blocked outright. Paste the sprite into the same document you reference it from.

Do all icons need the same viewBox?

No. Each symbol keeps its own viewBox — taken from the source file, or synthesised from its width and height — so icons drawn on 16, 24 and 512 unit grids can live in one sprite and each still scales correctly.

How do I change an icon’s colour?

Style the referencing <svg>, not the shapes inside — selectors cannot cross into the shadow content that <use> renders, but fill, stroke and currentColor inherit through it. The Color Editor converts icons to currentColor in one click first.

Why did my Feather or Lucide icons turn solid black?

Those sets declare fill="none" and stroke="currentColor" on the root svg element, and root attributes are not copied into the symbol. Put the same attributes on the referencing <svg class="icon"> — they inherit into the icon and it draws as outlines again.

Can the sprite live in a separate .svg file?

In current browsers, yes — <use href="sprite.svg#id"> works from the same origin. Cross-origin references are blocked, and a sprite loaded through <img> cannot be referenced at all; inline remains the most portable option.

Are my icon files uploaded?

No. Files are read, parsed and merged by your own browser. The sprite never touches a server.

How are the symbol ids chosen?

From the file names — lowercased, with anything outside letters, digits, hyphen and underscore turned into hyphens. Every id is editable in the list, which matters because ids must be unique across the whole page, not just the sprite.

What happened to the <title> elements in my files?

They are removed on purpose — a title inside a symbol would be stamped into every copy and announced even where the icon is decorative. Label at the point of use: aria-hidden for decorative icons, aria-label when the icon stands alone.

Is a sprite better than React icon components?

They solve different halves. Components suit the handful of icons in an app shell; a sprite suits the long tail and server-rendered pages. The React guide makes the case for the split, and the SVG to JSX tool covers the component half.

Notes

  • Each symbol keeps its own viewBox, so icons drawn on different grids can live in the same sprite.
  • Inline the sprite at the top of the document body. A sprite loaded through <img> cannot be referenced by <use>, and a cross-origin one is blocked outright.
  • Ids must be unique across the whole page, not just the sprite — prefix them if you ship more than one.

Related tools