Design

Using SVG in Next.js/React: Inline vs img vs SVGR Components

Illustration of three ways to use SVG in React/Next.js: inline markup, image asset, and reusable component blocks.
Illustration of three ways to use SVG in React/Next.js: inline markup, image asset, and reusable component blocks.

Using SVG in Next.js/React: Inline vs <img> vs Components

SVG in Next.js is easy—until you need to change the color, animate paths, or avoid bundling 500 icons into your JS.

There are 3 practical methods that cover 99% of real projects:

  1. Inline SVG (paste SVG markup in JSX)

  2. <img> / public folder (treat SVG as an asset URL)

  3. SVG as React components (SVGR approach)

Let’s break down when to use each, and how to do it without breaking accessibility.

Method 1: Inline SVG (best for theming + animation)

What it looks like

export function CheckIcon({ title = "Check" }) {
  return (
    <svg
      viewBox="0 0 24 24"
      width="24"
      height="24"
      role="img"
      aria-label={title}
    >
      <path
        d="M20 6L9 17l-5-5"
        fill="none"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}

Pros

  • Best control over fill/stroke

  • Easy to animate with CSS/Framer Motion

  • No asset loading requests (it’s in the HTML/JS)

Cons

  • Can clutter components if overused

  • Repeating the same SVG in many places can bloat your code

Use inline SVG when: it’s a UI icon you want to theme (currentColor), animate, or tweak per state.

Method 2: Public folder + <img> (best for “just show this SVG”)

Put your SVG in:
/public/icons/logo.svg

Then:

export default function Header() {
  return <img src="/icons/logo.svg" alt="SVGverseAI logo" width="140" height="28" />;
}

Pros

  • Simple and fast to implement

  • SVG stays out of your JS bundle

  • Great for logos/illustrations you don’t need to theme

Cons

  • You can’t easily change internal SVG colors with CSS (unless you use filters, which is messy)

  • Limited control for animation of internal paths

Use <img> when: the SVG is basically an image (logo, decorative illustration, badge).

Method 3: next/image for SVG (use carefully)

Next.js Image component extends <img> and can render SVGs too. Next.js+1

import Image from "next/image";
import logo from "./logo.svg";

export default function Page() {
  return <Image src={logo} alt="SVGverseAI logo" />;
}

Important note: vector images often don’t benefit from Next’s optimization the same way photos do. Next’s legacy Image docs even call out that unoptimized can be useful for SVG. Next.js

Rule:

  • If you’re using SVG like a normal asset, public + <img> is usually cleaner.

  • If you already use Image everywhere and want consistency, it can work—just don’t expect big “optimization wins.”

SVGR approach: import SVG as a React component (best for icon systems)

SVGR lets you do:

import Icon from "./icon.svg";

export function Button() {
  return <Icon aria-label="Settings" />;
}

SVGR has official guidance for configuring Next.js with @svgr/webpack. react-svgr.com

Pros

  • Perfect for design systems (icons as components)

  • You can enforce currentColor, add props, and standardize size

  • Works great with Tailwind/React patterns

Cons

  • Adds build configuration

  • Easy to accidentally bundle too many icons into JS if not organized

Theming: fill/stroke the right way

If you want CSS control, use:

  • fill="currentColor"

  • stroke="currentColor"

Then:

<span className="text-zinc-900 hover:text-zinc-500">
  <CheckIcon />
</span>

Avoid: hardcoded fills like fill="#000" inside icon SVGs if you want themable icons.

Accessibility: don’t ship “silent icons”

Best practices:

  • If the SVG is meaningful → ensure it has a label:

    • Inline: role="img" + aria-label="..." (or <title>)

    • <img>: always add alt="..."

  • If the SVG is purely decorative → hide it:

    • Inline: aria-hidden="true"

    • <img>: alt=""

Pros/cons summary (fast)

  • Inline SVG: best control, best theming, best animation

  • Public + <img>: best simplicity, best for logos/illustrations

  • SVGR component: best for icon libraries and scalable UI systems

(Community discussions often land on this exact split: inline/SVGR for icons, public assets for “image-like” SVGs.) Reddit+1

Best practice checklist

  • ✅ Icons you want to color via CSS → Inline or SVGR

  • ✅ Logos and illustrations → Public + <img>

  • ✅ Keep icon SVGs clean: currentColor, remove inline styles

  • ✅ Add accessibility labels

  • ✅ Optimize SVGs before shipping (minify, remove junk)

Internal reading: