DevToolBoxGRATUIT
Blog

SVG en composant React : Guide complet de conversion

8 min de lecturepar DevToolBox

Convertir SVG en composants React est essentiel pour le developpement frontend moderne. Ce guide couvre la conversion manuelle, les outils automatises, l'accessibilite et l'optimisation des performances.

Convertissez SVG en JSX avec notre outil gratuit.

Pourquoi convertir SVG en composants React ?

Les composants SVG offrent un controle total du style, des animations, le support des themes et le tree-shaking.

React traite les SVG comme des elements de premiere classe avec props, evenements et cycle de vie.

Le defi principal est la conversion des attributs HTML en equivalents JSX (camelCase).

Methode 1 : Conversion manuelle

Pour un SVG simple, la conversion manuelle est directe :

  1. Copiez le SVG brut.
  2. Remplacez class par className.
  3. Convertissez les attributs en camelCase.
  4. Encapsulez dans un composant React.

Voici un exemple avant/apres :

Raw SVG (before conversion)

<!-- Raw SVG from a design tool -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
     viewBox="0 0 24 24" class="icon-check"
     fill="none" stroke="currentColor" stroke-width="2"
     stroke-linecap="round" stroke-linejoin="round">
  <polyline points="20 6 9 17 4 12"></polyline>
</svg>

React Component (after conversion)

import React from 'react';

interface CheckIconProps {
  size?: number;
  color?: string;
  className?: string;
}

const CheckIcon: React.FC<CheckIconProps> = ({
  size = 24,
  color = 'currentColor',
  className = '',
}) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    width={size}
    height={size}
    viewBox="0 0 24 24"
    className={`icon-check ${className}`}
    fill="none"
    stroke={color}
    strokeWidth={2}           // was stroke-width
    strokeLinecap="round"     // was stroke-linecap
    strokeLinejoin="round"    // was stroke-linejoin
    role="img"
    aria-label="Checkmark"
  >
    <polyline points="20 6 9 17 4 12" />
  </svg>
);

export default CheckIcon;

Common SVG Attribute Conversions

HTML Attribute        JSX Equivalent
─────────────────────────────────────────
class                 className
fill-rule             fillRule
clip-path             clipPath
clip-rule             clipRule
fill-opacity          fillOpacity
stroke-width          strokeWidth
stroke-linecap        strokeLinecap
stroke-linejoin       strokeLinejoin
stroke-dasharray      strokeDasharray
stroke-dashoffset     strokeDashoffset
stroke-miterlimit     strokeMiterlimit
stroke-opacity        strokeOpacity
font-size             fontSize
font-family           fontFamily
text-anchor           textAnchor
text-decoration       textDecoration
dominant-baseline     dominantBaseline
alignment-baseline    alignmentBaseline
xlink:href            xlinkHref (deprecated)
xml:space             xmlSpace

Methode 2 : Conversion automatisee avec SVGR

SVGR est l'outil standard pour convertir SVG en composants React.

Utilisable en CLI, plugin webpack/Vite, ou API Node.js.

SVGR CLI

# Install SVGR
npm install -D @svgr/cli

# Convert a single SVG file to a React component
npx @svgr/cli --icon --typescript icon.svg

# Convert an entire directory of SVGs
npx @svgr/cli --icon --typescript --out-dir src/components/icons src/assets/svg/

# With SVGO optimization included
npx @svgr/cli --icon --svgo --typescript icon.svg

SVGR with webpack (React/Next.js)

// next.config.js (Next.js example)
module.exports = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      use: [
        {
          loader: '@svgr/webpack',
          options: {
            svgo: true,
            svgoConfig: {
              plugins: [
                { name: 'removeViewBox', active: false },
                { name: 'removeDimensions', active: true },
              ],
            },
            titleProp: true,    // adds title prop for a11y
            typescript: true,   // generates TypeScript
          },
        },
      ],
    });
    return config;
  },
};

// Usage in your component:
import ArrowIcon from './arrow.svg';

function Button() {
  return (
    <button>
      <ArrowIcon width={20} height={20} title="Navigate" />
      Next
    </button>
  );
}

SVGR with Vite

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import svgr from 'vite-plugin-svgr';

export default defineConfig({
  plugins: [
    react(),
    svgr({
      svgrOptions: {
        icon: true,
        typescript: true,
        svgo: true,
      },
    }),
  ],
});

// Usage with named import:
import { ReactComponent as Logo } from './logo.svg';
// or default import depending on config:
import Logo from './logo.svg?react';

SVGR supporte une configuration extensive via .svgrrc.json.

.svgrrc.json configuration

{
  "icon": true,
  "typescript": true,
  "svgo": true,
  "titleProp": true,
  "replaceAttrValues": {
    "#000": "currentColor",
    "#000000": "currentColor"
  },
  "svgoConfig": {
    "plugins": [
      { "name": "removeViewBox", "active": false },
      { "name": "removeDimensions", "active": true },
      { "name": "removeTitle", "active": false }
    ]
  },
  "template": null
}

SVG inline vs fichiers SVG externes

Deux approches principales avec des compromis differents :

SVG inline (composants JSX)

  • Avantages : Controle CSS/JS complet, props dynamiques, tree-shaking
  • Inconvenients : Augmente la taille du bundle JS

Fichiers SVG externes

  • Avantages : Cache independant, bundle JS plus petit
  • Inconvenients : Pas de style dynamique, requete HTTP supplementaire

Approche hybride recommandee : inline pour les icones, externe pour les grandes illustrations.

// Inline SVG as component (best for icons)
import SearchIcon from '@/icons/SearchIcon';

function SearchBar() {
  return (
    <div className="search-bar">
      <SearchIcon size={20} color="var(--text-muted)" />
      <input type="text" placeholder="Search..." />
    </div>
  );
}

// External SVG via img tag (best for large illustrations)
function HeroSection() {
  return (
    <section>
      <h1>Welcome</h1>
      <img
        src="/illustrations/hero-graphic.svg"
        alt="Developer tools illustration"
        width={600}
        height={400}
        loading="lazy"
      />
    </section>
  );
}

Accessibilite SVG dans React

Les SVG decoratifs doivent etre caches des lecteurs d'ecran, les SVG significatifs necessitent des labels.

// Meaningful SVG - conveys information
const WarningIcon = ({ message }: { message: string }) => (
  <svg
    role="img"
    aria-label={message}
    viewBox="0 0 24 24"
    width={24}
    height={24}
  >
    <title>{message}</title>
    <path d="M12 2L1 21h22L12 2zm0 4l7.5 13h-15L12 6z" fill="currentColor" />
    <path d="M11 10h2v5h-2zm0 6h2v2h-2z" fill="currentColor" />
  </svg>
);

// Decorative SVG - hidden from assistive technology
const DividerIcon = () => (
  <svg
    aria-hidden="true"
    focusable="false"
    viewBox="0 0 100 2"
    width={100}
    height={2}
  >
    <line x1="0" y1="1" x2="100" y2="1" stroke="currentColor" />
  </svg>
);

Regles cles d'accessibilite :

  • role="img" et aria-label pour les SVG significatifs
  • aria-hidden="true" pour les SVG decoratifs
  • Element title comme description de secours

Optimisation des performances

Strategies pour maintenir les performances avec les SVG :

Optimisez avec SVGO avant la conversion.

Utilisez React.memo pour les composants d'icones.

Chargement paresseux pour les grands ensembles d'icones.

Sprites SVG pour les icones repetees.

Preferez currentColor pour l'heritage de couleur.

// Memoized icon component - prevents unnecessary re-renders
import React from 'react';

interface IconProps extends React.SVGProps<SVGSVGElement> {
  size?: number;
}

const StarIcon = React.memo<IconProps>(({ size = 24, ...props }) => (
  <svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="currentColor"
    {...props}
  >
    <path d="M12 2l3.09 6.26L22 9.27l-5 4.87
             1.18 6.88L12 17.77l-6.18 3.25L7 14.14
             2 9.27l6.91-1.01L12 2z" />
  </svg>
));
StarIcon.displayName = 'StarIcon';

// Lazy-loaded icon set for code splitting
const ChartIcons = React.lazy(() => import('./ChartIconSet'));

function Dashboard() {
  return (
    <React.Suspense fallback={<div style={{ width: 24, height: 24 }} />}>
      <ChartIcons.BarChart size={32} />
    </React.Suspense>
  );
}

// SVG sprite with <use> for repeated icons
function SpriteIcon({ id, size = 24 }: { id: string; size?: number }) {
  return (
    <svg width={size} height={size} aria-hidden="true">
      <use href={`/icons/sprite.svg#${id}`} />
    </svg>
  );
}

Support TypeScript pour SVG

Typage correct des composants SVG avec TypeScript :

// types/svg.d.ts - Enable SVG imports as React components
declare module '*.svg' {
  import React from 'react';
  const SVGComponent: React.FC<React.SVGProps<SVGSVGElement>>;
  export default SVGComponent;
}

// For Vite with vite-plugin-svgr:
declare module '*.svg?react' {
  import React from 'react';
  const SVGComponent: React.FC<React.SVGProps<SVGSVGElement>>;
  export default SVGComponent;
}

// Reusable icon component type
interface IconComponentProps extends React.SVGProps<SVGSVGElement> {
  size?: number;
  color?: string;
  title?: string;
}

// Icon factory function with proper types
function createIcon(
  path: string,
  displayName: string
): React.FC<IconComponentProps> {
  const Icon: React.FC<IconComponentProps> = ({
    size = 24,
    color = 'currentColor',
    title,
    ...props
  }) => (
    <svg
      width={size}
      height={size}
      viewBox="0 0 24 24"
      fill="none"
      stroke={color}
      strokeWidth={2}
      strokeLinecap="round"
      strokeLinejoin="round"
      role={title ? 'img' : undefined}
      aria-label={title}
      aria-hidden={!title}
      {...props}
    >
      {title && <title>{title}</title>}
      <path d={path} />
    </svg>
  );
  Icon.displayName = displayName;
  return React.memo(Icon);
}

Generation de fichiers .d.ts pour les imports SVG.

SVG dans les projets Next.js

Configuration specifique avec @svgr/webpack pour Next.js.

// next.config.ts (Next.js 13+ with App Router)
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  webpack(config) {
    // Find the existing rule that handles SVG imports
    const fileLoaderRule = config.module.rules.find(
      (rule: { test?: RegExp }) => rule.test?.test?.('.svg')
    );

    config.module.rules.push(
      // Reapply the existing rule, but only for svg imports
      // ending in ?url (e.g. import iconUrl from './icon.svg?url')
      {
        ...fileLoaderRule,
        test: /\.svg$/i,
        resourceQuery: /url/,
      },
      // Convert all other *.svg imports to React components
      {
        test: /\.svg$/i,
        issuer: fileLoaderRule.issuer,
        resourceQuery: {
          not: [...(fileLoaderRule.resourceQuery?.not || []), /url/],
        },
        use: [
          {
            loader: '@svgr/webpack',
            options: {
              typescript: true,
              svgo: true,
              titleProp: true,
            },
          },
        ],
      }
    );

    // Modify the file loader rule to ignore *.svg
    fileLoaderRule.exclude = /\.svg$/i;

    return config;
  },
};

export default nextConfig;

Import direct de SVG comme composants React apres configuration.

Questions frequentes

Comment convertir SVG en composant React ?

Transformez les attributs HTML en JSX, encapsulez dans un composant et exportez. Utilisez SVGR ou notre outil en ligne.

Quelle difference entre SVG to JSX et SVG to React ?

SVG to JSX convertit la syntaxe. SVG to React ajoute le wrapper composant avec props et types.

Inline SVG ou img tag dans React ?

Inline pour les icones (< 5KB), img pour les grandes illustrations. Approche hybride recommandee.

Comment rendre les SVG accessibles ?

role="img" et aria-label pour les SVG significatifs, aria-hidden="true" pour les decoratifs.

SVG avec React Native ?

Oui, avec react-native-svg. SVGR a aussi un mode React Native.

Convertir SVG en composants React combine graphiques vectoriels et interactivite React. Utilisez notre outil en ligne ou SVGR.

Convertissez SVG en JSX avec notre outil gratuit.

Related Developer Tools and Guides

𝕏 Twitterin LinkedIn
Cet article vous a-t-il aidé ?

Restez informé

Recevez des astuces dev et les nouveaux outils chaque semaine.

Pas de spam. Désabonnez-vous à tout moment.

Essayez ces outils associés

SVGSVG to JSX/ReactJSXHTML to JSX

Articles connexes

SVG dans React : Du SVG brut aux composants optimisés

Apprenez à transformer du SVG brut en composants React performants. Optimisation SVGO, accessibilité, animations et props TypeScript.

SVG viewBox expliqué : Largeur, hauteur, mise à l'échelle et SVGs réactifs

Démystifiez l'attribut SVG viewBox. Comment min-x, min-y, width et height contrÎlent le systÚme de coordonnées.

HTML vers JSX : Tout ce qu'il faut savoir pour migrer vers React

Guide complet pour convertir du HTML en JSX pour React. className, objets style, balises auto-fermantes, gestionnaires d'événements et piÚges courants.