The three ways to use SVG icons
You can include an SVG in a web page three ways. Each has trade-offs:
| Method | Pros | Cons |
|---|---|---|
| Inline SVG | Styleable with CSS, scriptable, no extra HTTP request | Adds markup to every component that uses it |
| <img src> / CSS background | Cached by browser, clean HTML | Can't style internal colors with CSS |
| Framework component (JSX / .vue) | Reusable, props-driven, themeable | Requires a build step or conversion |
React and Next.js: inline SVG as a component
In React and Next.js, the most flexible approach is to turn the SVG into a component so you can control size, color, and behavior with props.
import { forwardRef, SVGProps } from "react"
const SaveIcon = forwardRef<SVGSVGElement, SVGProps<SVGSVGElement>>(
({ size = 24, color = "currentColor", ...props }, ref) => (
<svg
ref={ref}
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
stroke={color}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
{...props}
>
<path d="M5 12l5 5L19 7" />
</svg>
)
)
export default SaveIconUsing stroke="currentColor" (or fill="currentColor") lets the icon inherit the surrounding text color — hover states, focus rings, and dark mode work automatically.
In Next.js with the App Router, place the component in your component tree and use it like any other JSX element. No special image configuration is needed for inline SVGs.
Vue 3: inline SVG as a component
Vue handles inline SVG similarly — extract the SVG markup into a .vue component so you can bind size and color dynamically.
<template>
<svg
:width="size"
:height="size"
viewBox="0 0 24 24"
:stroke="color"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M5 12l5 5L19 7" />
</svg>
</template>
<script setup>
defineProps<{
size?: number
color?: string
}>()
const size = defineProps<{ size?: number }>().size ?? 24
const color = defineProps<{ color?: string }>().color ?? "currentColor"
</script>Converting SVG to JSX without rewriting by hand
Copying and pasting SVG markup into JSX by hand is error-prone — self-closing tags, attribute names (className vs class), and namespace handling all need care. A converter handles the syntax translation for you.
- Open the SVG to JSX, Vue & Svelte Converter.
- Paste your SVG code or upload an .svg file.
- Choose the target framework: React (TSX), Vue 3, or Svelte.
- Copy the generated component code into your project — see also Typed SVG Patterns in React & Server Components and Organizing Large React/Next.js Icon Libraries.
The conversion runs in your browser — nothing uploads to a server — and works for any SVG, including icons exported from Figma, Illustrator, or icon libraries.
Sizing and theming tips
- Use relative units. Pass
sizeas a prop rather than hardcoding width/height, so icons scale with their container. - currentColor for theming. Set
fill="currentColor"orstroke="currentColor"so icons follow text color and respectprefers-color-scheme. - Don't inline every icon. For pages with dozens of identical icons, consider an SVG sprite sheet instead of repeating markup.
Related SVG tools
Written by Achraf A., founder of TheFreeAITools.