SVG Sprites in React, Vue, and Modern Frameworks
Implement SVG sprite systems in React, Vue, Svelte, and other component-based frameworks. Learn about icon components, TypeScript integration, and framework-specific best practices.
Detailed Explanation
SVG Sprites in Modern JavaScript Frameworks
Using SVG sprites in React, Vue, and other component-based frameworks requires a slightly different approach than plain HTML. Here are the patterns for each major framework.
React
Create a reusable Icon component:
// Icon.tsx
interface IconProps {
name: string;
size?: number;
className?: string;
title?: string;
}
export function Icon({ name, size = 24, className, title }: IconProps) {
return (
<svg
width={size}
height={size}
className={className}
aria-hidden={!title}
role={title ? "img" : undefined}
aria-label={title}
>
{title && <title>{title}</title>}
<use href={`#icon-${name}`} />
</svg>
);
}
Usage:
<Icon name="home" size={20} />
<Icon name="search" title="Search" className="text-blue-500" />
Important: In React, use href (not xlinkHref) on the <use> element. The xlinkHref prop was deprecated in React 18.
Vue 3
<!-- SvgIcon.vue -->
<template>
<svg
:width="size"
:height="size"
:class="className"
:aria-hidden="!title"
:role="title ? 'img' : undefined"
:aria-label="title"
>
<title v-if="title">{{ title }}</title>
<use :href="`#icon-${name}`" />
</svg>
</template>
<script setup lang="ts">
defineProps<{
name: string;
size?: number;
className?: string;
title?: string;
}>();
</script>
Including the Sprite
In single-page applications, include the sprite in your root layout:
React (Next.js layout.tsx):
import spriteContent from "@/assets/sprite.svg?raw";
export default function Layout({ children }) {
return (
<html>
<body>
<div
dangerouslySetInnerHTML={{ __html: spriteContent }}
style={{ display: "none" }}
/>
{children}
</body>
</html>
);
}
Vue (App.vue):
<template>
<div v-html="spriteContent" style="display:none" />
<router-view />
</template>
TypeScript Integration
Create a type-safe icon name union:
// icons.ts
export const iconNames = [
"home", "search", "settings", "user", "mail"
] as const;
export type IconName = typeof iconNames[number];
Then use it in your Icon component props:
interface IconProps {
name: IconName; // Type-safe icon name
// ...
}
This gives you autocomplete and compile-time validation of icon names.
Use Case
React, Vue, and Svelte developers implementing icon systems in component-based applications, teams building design system component libraries, and developers migrating from individual SVG imports to a sprite-based approach.