Dev.to WebDev πŸ›  Dev πŸ‘ 0 πŸ“– 10 min read

How to Create an SVG Icon Sprite for Your Website

Build a small navigation example with Home, Search, and a dismiss button using three icons from the same set. You will paste SVG code into the free SVG Sprite Generator, copy its output, and use the resulting symbols in

How to Create an SVG Icon Sprite for Your Website

Build a small navigation example with Home, Search, and a dismiss button using three icons from the same set. You will paste SVG code into the free SVG Sprite Generator, copy its output, and use the resulting symbols in a web page. No framework or build plugin is needed.

Navigation demo showing Home, Search and a dismiss button

Once the generated sprite is included in your page, a visible icon needs only a reference to its symbol. Here is the Home link used in this example:

<a href="#home">
  <svg class="icon" width="24" height="24" aria-hidden="true" focusable="false">
    <use href="#icon-home"></use>
  </svg>
  Home
</a>
.icon { width: 1em; height: 1em; fill: currentColor; }

This short snippet assumes icon-home is already defined in the document. The steps below create that definition; section 3 contains the complete page you can copy.

When a sprite fits

A sprite defines each icon once inside a <symbol>. An <svg> containing <use> draws an instance wherever you need it. This is useful for repeated icons in plain HTML, server templates, and documentation. A small, deliberately chosen set is easier to maintain than a bundle of every available icon.

Sprites can reduce repeated markup, but they do not always improve performance. An inline sprite adds bytes to each HTML document; an external sprite needs a request but can be cached. Unused symbols still cost bytes. Measure your own pages. Separate SVGs or components may fit better when icons need different animations, per-instance path changes, or individual imports.

1. Choose three matching icons

Use the 24-pixel solid variants from HeroIcons: home-solid, magnifying-glass-solid, and x-mark-solid. Keep the same variant and grid rather than mixing outline, 16-pixel, and solid artwork.

On each icon page, use the basic Copy to Clipboard β†’ SVG action. Basic SVG copying is available without signing in; the separate download action requires a verified Member account. Neither an account nor Pro is required to use this generator. See Copy SVG code for that workflow.

The reproducible inputs below come from the same set's official Heroicons v2.2.0 sources. They use a 0 0 24 24 viewBox. Heroicons is distributed under the MIT license; retain its copyright and permission notice with redistributed copies. Save a copy of the linked license alongside your example as LICENSE-heroicons.txt. The generator does not create a license manifest for you.

For an exact reproduction, paste these complete SVG documents into separate input blocks:

Name: home

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" data-slot="icon">
  <path d="M11.47 3.841a.75.75 0 0 1 1.06 0l8.69 8.69a.75.75 0 1 0 1.06-1.061l-8.689-8.69a2.25 2.25 0 0 0-3.182 0l-8.69 8.69a.75.75 0 1 0 1.061 1.06l8.69-8.689Z"/>
  <path d="m12 5.432 8.159 8.159c.03.03.06.058.091.086v6.198c0 1.035-.84 1.875-1.875 1.875H15a.75.75 0 0 1-.75-.75v-4.5a.75.75 0 0 0-.75-.75h-3a.75.75 0 0 0-.75.75V21a.75.75 0 0 1-.75.75H5.625a1.875 1.875 0 0 1-1.875-1.875v-6.198a2.29 2.29 0 0 0 .091-.086L12 5.432Z"/>
</svg>

Name: magnifying-glass

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" data-slot="icon">
  <path fill-rule="evenodd" d="M10.5 3.75a6.75 6.75 0 1 0 0 13.5 6.75 6.75 0 0 0 0-13.5ZM2.25 10.5a8.25 8.25 0 1 1 14.59 5.28l4.69 4.69a.75.75 0 1 1-1.06 1.06l-4.69-4.69A8.25 8.25 0 0 1 2.25 10.5Z" clip-rule="evenodd"/>
</svg>

Name: x-mark

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" data-slot="icon">
  <path fill-rule="evenodd" d="M5.47 5.47a.75.75 0 0 1 1.06 0L12 10.94l5.47-5.47a.75.75 0 1 1 1.06 1.06L13.06 12l5.47 5.47a.75.75 0 1 1-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 0 1-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
</svg>

2. Generate the sprite

SVG Sprite Generator with three named Heroicons and generated output

  1. Open the SVG Sprite Generator. It starts with two blocks named icon-1 and icon-2.
  2. Replace the first name with home and paste the home SVG. Name the second magnifying-glass and paste its SVG.
  3. Click Add SVG Icon +. Name the new block x-mark and paste the third SVG. Use Remove for unwanted blocks; a named empty block prevents generation.
  4. Under Options, keep ID prefix as icon, Default size as 24, and HTML mode as Decorative. Leave Hide sprite by default and currentColor CSS helper checked.
  5. Click Generate Sprite. Check the previews and any errors or warnings. The output should contain icon-home, icon-magnifying-glass, and icon-x-mark.
  6. Select the Sprite tab and click Copy output. The other tabs are HTML snippet, CSS, and React. Copy each snippet you need.

This interface accepts pasted SVG markup, not uploaded files or a selection from Collections. It processes the markup in your browser. There is no file download button: you copy text and save files yourself. Load example set replaces the inputs with the tool's own samples; Clear restores two empty blocks. After editing names, SVGs, or options, click Generate Sprite again before copying to avoid stale output.

3. Use the output in a web page

Save the following as index.html. The hidden SVG is the actual generated sprite. It belongs once inside the document body; the visible SVGs reference its symbol IDs. The Home and Search icons repeat link text, so they are decorative. The icon-only dismiss button has its accessible name on the button and actually hides the notice.

Complete example: index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>SVG sprite demo</title>
  <style>body { margin: 2rem; font: 18px/1.5 system-ui, sans-serif; color: #163b66; background: #fff; }
nav { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
a { color: inherit; }
button { font: inherit; color: inherit; background: #eef4ff; border: 1px solid #7c94ad; border-radius: .5rem; padding: .6rem; cursor: pointer; }
:focus-visible { outline: 3px solid #b45309; outline-offset: 4px; }
.icon { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
.icon-button .icon { width: 24px; height: 24px; }
.large { font-size: 32px; color: #9f1239; }
.dark { margin-top: 1rem; padding: 1rem; color: #e2e8f0; background: #172033; }
</style>
</head>
<body>
<!-- Heroicons v2.2.0, MIT; see LICENSE-heroicons.txt. -->
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" style="position: absolute; width: 0; height: 0; overflow: hidden;">
  <symbol id="icon-home" viewBox="0 0 24 24">
      <g xmlns="http://www.w3.org/2000/svg" fill="currentColor">
        <path d="M11.47 3.841a.75.75 0 0 1 1.06 0l8.69 8.69a.75.75 0 1 0 1.06-1.061l-8.689-8.69a2.25 2.25 0 0 0-3.182 0l-8.69 8.69a.75.75 0 1 0 1.061 1.06l8.69-8.689Z"/>
        <path d="m12 5.432 8.159 8.159c.03.03.06.058.091.086v6.198c0 1.035-.84 1.875-1.875 1.875H15a.75.75 0 0 1-.75-.75v-4.5a.75.75 0 0 0-.75-.75h-3a.75.75 0 0 0-.75.75V21a.75.75 0 0 1-.75.75H5.625a1.875 1.875 0 0 1-1.875-1.875v-6.198a2.29 2.29 0 0 0 .091-.086L12 5.432Z"/>
      </g>
    </symbol>
  <symbol id="icon-magnifying-glass" viewBox="0 0 24 24">
      <g xmlns="http://www.w3.org/2000/svg" fill="currentColor">
        <path fill-rule="evenodd" d="M10.5 3.75a6.75 6.75 0 1 0 0 13.5 6.75 6.75 0 0 0 0-13.5ZM2.25 10.5a8.25 8.25 0 1 1 14.59 5.28l4.69 4.69a.75.75 0 1 1-1.06 1.06l-4.69-4.69A8.25 8.25 0 0 1 2.25 10.5Z" clip-rule="evenodd"/>
      </g>
    </symbol>
  <symbol id="icon-x-mark" viewBox="0 0 24 24">
      <g xmlns="http://www.w3.org/2000/svg" fill="currentColor">
        <path fill-rule="evenodd" d="M5.47 5.47a.75.75 0 0 1 1.06 0L12 10.94l5.47-5.47a.75.75 0 1 1 1.06 1.06L13.06 12l5.47 5.47a.75.75 0 1 1-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 0 1-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
      </g>
    </symbol>
</svg>

<h1>SVG sprite demo</h1>
<nav aria-label="Demo navigation">
  <a href="#home"><svg class="icon" width="24" height="24" aria-hidden="true" focusable="false"><use href="#icon-home"></use></svg> Home</a>
  <a href="#search"><svg class="icon" width="24" height="24" aria-hidden="true" focusable="false"><use href="#icon-magnifying-glass"></use></svg> Search</a>
  <button class="icon-button" type="button" aria-label="Dismiss notice"
    onclick="document.getElementById('notice').hidden = true"><svg class="icon" width="24" height="24" aria-hidden="true" focusable="false"><use href="#icon-x-mark"></use></svg></button>
</nav>
<p id="notice">This is a dismissible demo notice.</p>
<section id="home"><h2>Home</h2><p>One sprite, three reusable symbols.</p></section>
<section id="search"><h2>Search</h2><p>This link is a navigation example, not a search engine.</p></section>
<p class="large"><svg class="icon" width="24" height="24" aria-hidden="true" focusable="false"><use href="#icon-home"></use></svg> A larger, differently colored instance</p>
<div class="dark"><svg class="icon" width="24" height="24" aria-hidden="true" focusable="false"><use href="#icon-magnifying-glass"></use></svg> The same icon on a dark background</div>
<p>Icons: Heroicons by Tailwind Labs / Refactoring UI Inc, MIT. Keep LICENSE-heroicons.txt with redistributed copies.</p>
</body>
</html>

The generator produces the sprite and small snippets, not the surrounding page, navigation, or dismiss behavior. The example above supplies those parts. The generated wrapper is absolutely positioned with zero width and height, keeping referenced definitions available; its symbols are referenced by the visible SVG instances. Test this pattern with your target browsers, especially if you introduce gradients or filters.

4. Control size and color

The viewBox describes the artwork's coordinate system, not its displayed pixel size. Keep it on each symbol. The CSS helper sets width and height to 1em, so these icons follow their element's font size. The 24-pixel width and height attributes in a generated snippet are overridden by that CSS. Our button deliberately overrides the helper with 24-pixel dimensions; the larger paragraph uses a 32-pixel font size.

fill: currentColor makes this solid artwork follow CSS color. Change the surrounding text color to recolor its icons. The helper does not rewrite hard-coded colors inside paths, and it is a fill helper, not a stroke conversion. Keep intentional multicolor artwork unchanged. See MDN's currentColor reference.

Outline icons keep their paint settings. Supported root presentation attributes, including fill="none", stroke="currentColor", and stroke-width, are preserved on an internal group. Child shapes can still override them. Paste the complete SVG; no manual group wrapper is needed. The fill helper does not turn a preserved outline into a filled icon.

The preview renders the generated symbol. Root style and class are not copied; use explicit SVG presentation attributes. Root viewport effects such as clip-path, mask, filter, transform and vector-effect are not transferred and produce warnings. Review those warnings and the final appearance for complex artwork.

5. Optionally save an external sprite

Save the copied Sprite output as sprite.svg next to your HTML. Remove the inline sprite from that page and use a filename plus a fragment:

<svg class="icon" width="24" height="24" aria-hidden="true" focusable="false">
  <use href="sprite.svg#icon-home"></use>
</svg>

Keep the same CSS. Serve both files from the same origin using your project's local development server. Do not test external references by double-clicking the HTML file: file:// restrictions can prevent the SVG from loading. If Python is installed, run this command in the folder containing both files:

python -m http.server 8000 --bind 127.0.0.1

Open http://127.0.0.1:8000/index.html. Stop the server with Ctrl+C. An external sprite requires deployment of the asset as well as the HTML; check its URL, response type, caching, and your browser support. Do not assume a sprite on another domain will work just by enabling CORS. MDN documents external use references and same-origin restrictions.

Common problems and fixes

  • No output: remove unused empty blocks and paste one complete, valid SVG document per input. Fix the reported XML error before generating again.
  • Blank icon: compare the exact href fragment with the generated ID. A name like β€œHome Icon” becomes icon-home-icon, not icon-home. Keep input names unique and inspect final IDs; do not rely on suffixing to resolve every possible collision.
  • Wrong size or clipping: preserve the source viewBox and check CSS dimensions. The tool can infer a viewBox from positive numeric width and height (including px), but it cannot recover arbitrary missing coordinate information.
  • Black or missing outline: check the source fill and stroke settings and any generator warnings. A fixed fill on a child path will also override inherited color. Verify both light and dark backgrounds.
  • Broken gradients or masks: review rewritten internal IDs and every reference. This tool removes some obvious unsafe content but is not a comprehensive sanitizer for untrusted SVG. Use reviewed sources.
  • External sprite missing: use HTTP, check the request succeeds, and keep the asset on the same origin. Recheck the deployed path after moving files.
  • Repeated or missing accessible labels: hide decorative SVGs and name their controls. If you choose Labelled mode for a meaningful standalone icon, adapt its title and make title IDs unique for every repeated instance. The generated title IDs are based on symbol names. See the WAI button pattern and SVG icon accessibility guide.

Keep the workflow small

Start with three icons, review their actual use sites, and keep the source SVGs and license notice beside your generated output. Try the SVG Sprite Generator with your next small set of interface icons.

For more options, read the generator documentation. If your project needs automated generation, see Build an SVG Sprite for Modern Vite, React, and Vue Apps. For per-icon components, see Use SVG Icons in React with Vite and SVGR or the [SVG to Component Converter](https://svgicons.com/tools/svg-

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.