How to Use SVG Icons: A Practical Guide for Modern Web Apps

Learn the most reliable ways to use SVG icons in Astro, React, and plain HTML. Includes accessibility, performance, and production-ready examples.

Amit Yadav
Amit Yadav

SVG icons are the default choice for modern interfaces because they stay sharp at any size, are easy to style, and can be optimized aggressively.

Why teams standardize on SVG icons

  • Crisp on every display — no blur on high-DPI screens
  • Easy to theme — use currentColor and inherit from text color
  • Fast to ship — tiny files once optimized
  • Flexible — inline, component-based, or CDN-hosted
Tip

Pick one icon style per product surface. Mixing many packs on one screen makes interfaces feel inconsistent.

1) Inline SVG (best control)

Inline SVG gives full control over paths, fill, stroke, and animation.

<button class="icon-button" aria-label="Open menu">
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 24 24"
    width="20"
    height="20"
    fill="none"
    stroke="currentColor"
    stroke-width="2"
    stroke-linecap="round"
    stroke-linejoin="round"
    aria-hidden="true"
  >
    <line x1="3" y1="6" x2="21" y2="6" />
    <line x1="3" y1="12" x2="21" y2="12" />
    <line x1="3" y1="18" x2="21" y2="18" />
  </svg>
</button>
.icon-button {
  color: #334155;
}

.icon-button:hover {
  color: #2563eb;
}

2) Referencing SVG with img (simple and cacheable)

Use this when you only need display and don’t need CSS control of paths.

<img src="/icons/logo.svg" alt="Company logo" width="24" height="24" />
Warning

If you use img, you cannot change stroke/fill colors via normal CSS selectors inside the SVG.

3) React component icons (best developer experience)

For React and Astro islands, component icons are usually the fastest workflow.

import { Home, Search } from 'lucide-react';

export function Toolbar() {
  return (
    <nav className="flex items-center gap-3">
      <button aria-label="Home">
        <Home className="h-5 w-5" />
      </button>
      <button aria-label="Search">
        <Search className="h-5 w-5" />
      </button>
    </nav>
  );
}

4) CDN-hosted icon URLs (quick prototyping)

For broad icon catalogs, fetch SVG directly from your icon API:

<img
  src="https://api.iconify.design/lucide/home.svg"
  alt="Home icon"
  width="24"
  height="24"
/>

This is great for prototypes and content pages, but for critical UI controls use local bundles or pre-resolved components where possible.

Accessibility checklist

  • Decorative icon: add aria-hidden="true"
  • Interactive icon button: add a meaningful aria-label
  • Avoid relying on icon-only meaning when critical; pair with text
<button aria-label="Delete file" className="inline-flex items-center gap-2">
  <Trash2 className="h-4 w-4" aria-hidden="true" />
  <span>Delete</span>
</button>

Performance checklist

  • Run SVGs through SVGO before shipping
  • Reuse the same icon set per surface
  • Prefer CSS transform and opacity for icon animations
  • Avoid very complex path-heavy icons in dense lists

Choose icon size fast

Use this helper to pick practical icon size tokens for web and mobile UI.

Icon Size Advisor

Pick your UI context and get a practical icon size recommendation.

Recommended tokens
16px20px24px32px
Nearest match
24px

For All SVG Icons content and examples:

  1. Use fenced code blocks in MDX for built-in syntax highlighting
  2. Use IconGrid for visual icon previews in blogs
  3. Keep IconPreview optional for single-icon demos only

That combination keeps blog content fast, readable, and easier to maintain over time.

Share this post