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 :
- Copiez le SVG brut.
- Remplacez class par className.
- Convertissez les attributs en camelCase.
- 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 xmlSpaceMethode 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.svgSVGR 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
- SVG to JSX Converter - Convert SVG markup to valid JSX for React
- HTML to JSX Converter - Convert any HTML to JSX including SVG
- SVG Optimizer - Optimize and minify SVG files with SVGO
- SVG Optimization for React - Advanced SVG optimization techniques
- SVG viewBox Explained - Understanding SVG coordinate systems
- HTML to JSX Migration Guide - Complete HTML to JSX conversion reference
- CSS to Tailwind Migration - Modernize your styling alongside SVG components
- JSON to TypeScript - Generate TypeScript types from JSON data