Usar SVG en React y Next.js: Guía de Integración Completa
Domina la integración de SVG en aplicaciones React y Next.js. Aprende métodos de importación, patrones de componentes, optimización y mejores prácticas para el desarrollo web moderno.

Founder of VectoSolve
Self-taught developer, founder and sole developer of VectoSolve since 2024. He builds the conversion engine and the cutting, embroidery and 3D printing exports.
How this article was made: drafted with AI assistance, then edited and fact-checked before publication. About the author
Key Takeaways
- React ofrece cuatro métodos principales de importación SVG: import de imagen, SVG inline, componentes SVGR e imports dinámicos
- SVGR con la configuración webpack de Next.js ofrece el mejor equilibrio entre experiencia de desarrollador y control en tiempo de ejecución
- Los componentes de iconos reutilizables con props de TypeScript (size, color, className) mantienen tu código DRY
- Framer Motion se integra nativamente con elementos SVG para animaciones de trazados y formas basadas en springs
-
Siempre agrega
aria-labeloaria-hiddena los iconos SVG para la accesibilidad de lectores de pantalla
SVG en el Desarrollo React Moderno
Los SVG son esenciales para las aplicaciones React modernas, ofreciendo gráficos nítidos a cualquier escala. Esta guía cubre cada método de uso de SVG en proyectos React y Next.js.
Métodos de Importación
1. Import de Imagen Estándar
Enfoque más simple:
import logo from './logo.svg';
function Header() {
return <img src={logo} alt="Logo" className="logo" />;
}
Ventajas: Simple, familiar
Desventajas: Sin acceso a estilos/manipulación
2. Componentes SVG Inline
Control total:
function Icon() {
return (
<svg viewBox="0 0 24 24" className="icon">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5"/>
</svg>
);
}
Ventajas: Acceso completo a CSS/JS
Desventajas: Verboso, no se puede cambiar fácilmente la fuente
3. SVGR (Componente React)
Importar como componente:
import { ReactComponent as Logo } from './logo.svg';
function Header() {
return <Logo className="logo" fill="currentColor" />;
}
Ventajas: Lo mejor de ambos mundos
Desventajas: Requiere configuración
4. Import Dinámico
Para code splitting:
import dynamic from 'next/dynamic';
const DynamicIcon = dynamic(() => import('./icons/chart.svg'));
function Dashboard() {
return <DynamicIcon />;
}
Pro Tip: Para la mayoría de los proyectos React, SVGR es el enfoque recomendado. Te permite importar SVG como componentes React con soporte completo de props mientras mantienes los archivos SVG separados para edición fácil en herramientas de diseño.
Configuración SVGR
Configuración Next.js
// next.config.js
module.exports = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack'],
});
return config;
},
};
Con Fallback de URL
// next.config.js
module.exports = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
issuer: /\.[jt]sx?$/,
use: [
{
loader: '@svgr/webpack',
options: {
svgoConfig: {
plugins: [{
name: 'removeViewBox',
active: false
}]
}
}
},
'url-loader'
],
});
return config;
},
};
A Full Year of Conversions for $49
Starter Annual: 25 conversions every month, $49 for the whole year. That is about $4.08 a month · Cancel anytime
Get the Annual DealPatrones de Componentes
Componente de Icono Reutilizable
interface IconProps {
name: string;
size?: number;
color?: string;
className?: string;
}
export function Icon({ name, size = 24, color = 'currentColor', className }: IconProps) {
return (
<svg
width={size}
height={size}
fill={color}
className={className}
>
<use href={`/sprites.svg#${name}`} />
</svg>
);
}
// Uso
<Icon name="search" size={20} color="#333" />
Componente de Biblioteca de Iconos
// icons/index.tsx
import { FC, SVGProps } from 'react';
interface IconComponentProps extends SVGProps<SVGSVGElement> {
size?: number;
}
const createIcon = (path: string): FC<IconComponentProps> => {
return function IconComponent({ size = 24, ...props }) {
return (
<svg
viewBox="0 0 24 24"
width={size}
height={size}
fill="currentColor"
{...props}
>
<path d={path} />
</svg>
);
};
};
export const SearchIcon = createIcon('M15.5 14h-.79l-.28-.27...');
export const HomeIcon = createIcon('M10 20v-6h4v6h5v-8h3L12...');
Estilizar SVG en React
Estilos CSS
/* styles.css */
.icon {
width: 24px;
height: 24px;
fill: currentColor;
transition: fill 0.2s;
}
.icon:hover {
fill: #0066cc;
}
Styled Components
import styled from 'styled-components';
const StyledSvg = styled.svg`
width: ${props => props.size || 24}px;
height: ${props => props.size || 24}px;
fill: ${props => props.color || 'currentColor'};
transition: fill 0.2s;
&:hover {
fill: ${props => props.hoverColor || props.color};
}
`;
Tailwind CSS
<svg
className="w-6 h-6 fill-current text-gray-600 hover:text-blue-500 transition-colors"
viewBox="0 0 24 24"
>
<path d="..."/>
</svg>
"El mejor flujo de trabajo SVG en React es aquel donde los diseñadores exportan vectores limpios y los desarrolladores los importan como componentes de primera clase — sin pasos de conversión manual entre medias.
Animación en React
Animación CSS
function LoadingSpinner() {
return (
<svg className="animate-spin" viewBox="0 0 24 24">
<circle
className="opacity-25"
cx="12" cy="12" r="10"
stroke="currentColor" strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
/>
</svg>
);
}
Framer Motion
import { motion } from 'framer-motion';
function AnimatedIcon() {
return (
<motion.svg
viewBox="0 0 24 24"
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ type: 'spring' }}
>
<motion.path
d="M12 2L2 22h20L12 2z"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
/>
</motion.svg>
);
}
Free SVG Tools for Crafters
Design Checker · Color Separator · Mat Preview · Offset Generator · Text to SVG
Check Your SVG FreeEstrategias de Optimización
Optimización en Tiempo de Compilación
// svgo.config.js
module.exports = {
plugins: [
'preset-default',
'removeDimensions',
{ name: 'removeViewBox', active: false },
{ name: 'prefixIds', params: { prefix: 'svg-' } }
]
};
Code Splitting
// Carga perezosa de iconos pesados
const ChartIcon = lazy(() => import('./icons/Chart'));
function Dashboard() {
return (
<Suspense fallback={<div className="icon-placeholder" />}>
<ChartIcon />
</Suspense>
);
}
Nunca elimines viewBox durante la optimización SVGO. Sin viewBox, los SVG pierden su capacidad de escalar de forma responsive. Siempre configura removeViewBox: false en tu configuración SVGO.
Accesibilidad en React
Patrón de Icono Accesible
interface AccessibleIconProps {
label: string;
children: React.ReactNode;
}
function AccessibleIcon({ label, children }: AccessibleIconProps) {
return (
<span role="img" aria-label={label}>
{children}
</span>
);
}
// Uso
<AccessibleIcon label="Buscar">
<SearchIcon />
</AccessibleIcon>
Botón con Icono
function IconButton({ icon: Icon, label, onClick }) {
return (
<button
onClick={onClick}
aria-label={label}
className="icon-button"
>
<Icon aria-hidden="true" />
</button>
);
}
Integración con VectoSolve
Flujo de Trabajo
Usar VectoSolve con React:
- Convertir imágenes a SVG
- Descargar la salida optimizada
- Importar en tu proyecto React
- Usar el método preferido de arriba
Beneficios de los Archivos Optimizados
Los SVG de VectoSolve son:
- Optimizados para uso web
- Listos para import SVGR
- Datos de trazado limpios
- Fáciles de estilizar
A Full Year of Conversions for $49
Starter Annual: 25 conversions every month, $49 for the whole year. That is about $4.08 a month · Cancel anytime
Get the Annual DealConclusión
React ofrece múltiples formas de trabajar con SVG, cada una con sus compromisos. Elige el enfoque que se adapte a tus necesidades: imports de imagen simples para uso básico, SVGR para control total, o patrones de componentes para sistemas de iconos. Comienza con SVG limpios y optimizados de VectoSolve para los mejores resultados.
| Método de Import SVG | Control Runtime | Impacto en Bundle | Ideal Para |
|---|---|---|---|
| <img src> import | Ninguno | Petición HTTP separada | Imágenes decorativas estáticas |
| SVG inline JSX | Total (props, eventos, CSS) | Aumenta tamaño del componente | Iconos interactivos, animaciones |
| Componente SVGR | Total (props tipadas, tree-shaking) | Chunk por componente | Bibliotecas de iconos, design systems |
| Import dinámico | Total (después de cargar) | Code-split, carga perezosa | SVG bajo el fold o condicionales |
Fuentes y Lecturas Adicionales
- MDN Web Docs: SVG in HTML — Referencia para integrar SVG en JSX y entender la interacción SVG-DOM
- web.dev: Code Splitting — Guía de Google sobre carga perezosa e imports dinámicos para un tamaño de bundle óptimo
- CSS-Tricks: SVG in React — Patrones prácticos para usar componentes SVG en proyectos React y Next.js
- Smashing Magazine: React Components — Mejores prácticas para construir bibliotecas de componentes SVG reutilizables y accesibles