Skip to content
Technical

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.

Robin Monteiro25 de enero de 202610 de octubre de 202610 min
Use this article with an AI assistant:
.md
Usar SVG en React y Next.js: Guía de Integración Completa
R
Robin Monteiro

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

Image vectorizationCutting machine filesEmbroidery filesSVG
Free previewNo signupFull-quality output

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-label o aria-hidden a 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.

Uso de componentes SVG en aplicaciones React y Next.js
SVG en React: desde imports simples hasta sistemas de iconos animados y accesibles

Métodos de Importación

1. Import de Imagen Estándar

Enfoque más simple:

jsx
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:

jsx
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:

jsx
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:

jsx
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

javascript
// next.config.js
module.exports = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      use: ['@svgr/webpack'],
    });
    return config;
  },
};

Con Fallback de URL

javascript
// 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 Deal

Patrones de Componentes

Componente de Icono Reutilizable

jsx
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

jsx
// 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...');
Iconos SVG optimizados para aplicaciones web y design systems
Construir un sistema de iconos SVG escalable en React con TypeScript

Estilizar SVG en React

Estilos CSS

css
/* styles.css */
.icon {
  width: 24px;
  height: 24px;
  fill: currentColor;
  transition: fill 0.2s;
}

.icon:hover {
  fill: #0066cc;
}

Styled Components

jsx
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

jsx
<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.

— Kent C. Dodds, Educador React

Animación en React

Animación CSS

jsx
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

jsx
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 Free

Estrategias de Optimización

Optimización en Tiempo de Compilación

javascript
// svgo.config.js
module.exports = {
  plugins: [
    'preset-default',
    'removeDimensions',
    { name: 'removeViewBox', active: false },
    { name: 'prefixIds', params: { prefix: 'svg-' } }
  ]
};

Code Splitting

jsx
// 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

jsx
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

jsx
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:

  1. Convertir imágenes a SVG
  2. Descargar la salida optimizada
  3. Importar en tu proyecto React
  4. 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 Deal

Conclusió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.

Obtén SVG Listos para React


Método de Import SVGControl RuntimeImpacto en BundleIdeal Para
<img src> importNingunoPetición HTTP separadaImágenes decorativas estáticas
SVG inline JSXTotal (props, eventos, CSS)Aumenta tamaño del componenteIconos interactivos, animaciones
Componente SVGRTotal (props tipadas, tree-shaking)Chunk por componenteBibliotecas de iconos, design systems
Import dinámicoTotal (después de cargar)Code-split, carga perezosaSVG bajo el fold o condicionales

Fuentes y Lecturas Adicionales

Tags:
React
Next.js
SVG
componentes
desarrollo web
Share:

Try VectoSolve Now

Convert your images to high-quality SVG vectors with AI

AI-Powered Vectorization

Ready to vectorize your images?

Convert your PNG, JPG, and other images to high-quality, scalable SVG vectors in seconds.