En une phrase
SVG vers JSX transforme le code de votre image vectorielle en un composant React réutilisable, le rendant dynamique et contrôlable avec des props au lieu d'être un simple fichier statique.
Le problème que ça résout
Au bon vieux temps du web (genre, il y a cinq ans), si vous vouliez afficher une icône SVG, vous l'auriez probablement balancée dans une balise <img> : <img src="/icons/user.svg" alt="User profile" />. Et voilà le travail. On met en prod.
Mais cette approche simpliste est un peu un piège. Votre SVG est désormais une boîte noire. Vous voulez changer sa couleur quand l'utilisateur survole le bouton qui la contient ? Pas de bol. Le navigateur la traite comme n'importe quel autre fichier image (un JPG, un PNG), et vous ne pouvez pas facilement styler ses entrailles avec du CSS. Animer un des tracés à l'intérieur de l'icône ? Nope. Changer sa couleur pour un thème sombre ? Vous allez devoir créer un tout nouveau fichier (user-white.svg) et écrire de la logique pour intervertir le src. Ça devient vite le bazar.
« Aha ! » se dit le développeur malin. « Le SVG, c'est juste du balisage XML ! Je n'ai qu'à copier le code du fichier .svg et le coller directement dans le return de mon composant ! »
// MyComponent.js
const MyComponent = () => (
<div>
<p>My Profile</p>
{/* I just pasted this from a .svg file! */}
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 12C14.21 12 16 10.21 16 8C16 5.79 14.21 4 12 4C9.79 4 8 5.79 8 8C8 10.21 9.79 12 12 12ZM12 14C9.33 14 4 15.34 4 18V20H20V18C20 15.34 14.67 14 12 14Z" fill="black"/>
</svg>
</div>
);
C'est ce qu'on appelle l'« inlining » (ou l'intégration en ligne), et c'est un grand pas en avant. Maintenant, le SVG fait partie du DOM, et vous pouvez le styler en CSS. Mais vous avez juste échangé un problème contre un autre.
- C'est lourdingue : Ce pavé de code SVG rend votre composant plus difficile à lire. Imaginez si vous aviez cinq icônes dedans.
- Ce n'est pas réutilisable : Besoin de cette icône utilisateur ailleurs ? Préparez-vous à copier-coller ce pavé de code partout.
- Ce n'est pas du JSX : React a son propre dialecte de HTML. Les attributs comme
stroke-widthdoivent être en camelCase (strokeWidth), etclassdevientclassName. Oublier de les convertir peut entraîner des erreurs silencieuses ou des avertissements bien bruyants dans la console.
La vraie solution, c'est de traiter les icônes non pas comme des assets statiques, mais comme des citoyens de première classe de votre écosystème de composants. Ce que vous voulez, c'est <UserIcon color="blue" size={24} />. C'est le problème que la conversion SVG vers JSX résout : elle automatise le code répétitif (le boilerplate) pour transformer du balisage SVG brut en un composant React propre, réutilisable et piloté par les props.
Comment ça marche sous le capot
Transformer un bloc de texte en un composant React bien propre peut sembler magique, mais c'est un processus prévisible, étape par étape. Soulevons le rideau.
Étape 1 : Parser le balisage SVG
D'abord, l'outil doit comprendre le SVG. Comme le SVG est un dialecte du XML, il peut être « parsé » (analysé) en une structure en arbre de nœuds, tout comme un document HTML. Chaque élément (<svg>, <path>, <g>, etc.) devient un nœud, et ses attributs (width, fill, d, etc.) deviennent des propriétés de ce nœud.
Donc, ceci :
<svg width="24" height="24">
<path fill-rule="evenodd" d="..." />
</svg>
Est compris par le parser comme un arbre :
- nœud
svgavec les attributswidth="24"etheight="24"- nœud
pathavec les attributsfill-rule="evenodd"etd="..."
- nœud
Étape 2 : La « JSX-ification » des attributs
C'est là que la traduction spécifique à React se produit. Le parser parcourt l'arbre de nœuds et convertit les attributs pour qu'ils soient conformes au JSX.
- Passage en camelCase : Tout attribut avec un tiret (en kebab-case) est converti en camelCase.
fill-ruledevientfillRule,stroke-widthdevientstrokeWidth. - Mapping des mots-clés : Les mots-clés réservés de JavaScript sont remplacés. Le plus courant est
class, qui devientclassName. - Attributs de style : Un attribut
style="fill:red; stroke:blue"est converti en un objet JavaScript :style={{ fill: 'red', stroke: 'blue' }}.
Ainsi, <path fill-rule="evenodd" class="icon-path"> se transforme en son équivalent JSX : <path fillRule="evenodd" className="icon-path">.
Étape 3 : L'encapsulation dans un composant
Maintenant que l'arbre SVG parle couramment le JSX, l'étape suivante consiste à l'envelopper dans la structure standard d'un composant fonctionnel React. La version la plus simple ressemble à ça :
import React from 'react';
const MyIcon = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24">
{/* ... tous les tracés et autres éléments "JSX-ifiés" ... */}
</svg>
);
};
export default MyIcon;
Cela vous donne déjà un composant réutilisable <MyIcon />, ce qui est une belle victoire. Mais la vraie puissance vient du fait de le rendre dynamique.
Étape 4 : Ajout des props et de currentColor
C'est l'ingrédient secret. Un bon convertisseur ne se contente pas de coder en dur les attributs d'origine du SVG. Il les rend configurables.
Le « spread » des props : Le composant est modifié pour accepter des props et les « étaler » (spread) sur l'élément
<svg>racine. C'est souvent fait avec la syntaxe...rest. Vous pouvez maintenant passer n'importe quel attribut SVG standard (commewidth,height,classNameouaria-label) directement à votre composant.L'astuce
currentColor: Ça, ça change la donne pour le style. Le convertisseur va trouver les attributsfilletstrokecodés en dur qui définissent la couleur de l'icône (ex:fill="#000000") et les remplacer par le mot-clé CSS spécialcurrentColor.
currentColor dit au navigateur : « Quelle que soit la propriété CSS color sur cet élément, utilise-la pour le fill/stroke. » Cela signifie que votre icône se comporte désormais comme du texte. Si vous enveloppez votre icône dans une div et que vous définissez color: blue, l'icône devient bleue.
// Le composant amélioré
const MyIcon = ({ color = 'currentColor', size = 24, ...rest }) => {
return (
<svg
width={size}
height={size}
fill={color} // ou appliqué directement aux tracés
{...rest}
>
<path d="..." fill="currentColor" />
</svg>
);
};
Étape 5 : Transférer les refs (Forwarding Refs)
Parfois, vous avez besoin d'obtenir une référence directe sur l'élément DOM <svg> réel depuis un composant parent, peut-être pour mesurer sa position ou l'utiliser avec une librairie tierce. Un composant fonctionnel normal cache sa structure DOM interne. La solution est React.forwardRef.
Un convertisseur sophistiqué enveloppera le composant dans React.forwardRef, qui crée un conduit pour passer une ref du parent directement à la balise <svg> sous-jacente.
Le composant final, prêt pour la prod, ressemble souvent à quelque chose comme ça (exemple en TypeScript) :
import * as React from 'react';
type Props = React.SVGProps<SVGSVGElement>;
const MyIcon = React.forwardRef<SVGSVGElement, Props>((props, ref) => (
<svg ref={ref} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" {...props}>
<path d="..." fill="currentColor" />
</svg>
));
MyIcon.displayName = 'MyIcon'; // Pratique pour le débogage
export default MyIcon;
Histoires vécues
Le cauchemar du theming
Une équipe front-end construisait une superbe application web avec un mode clair et un mode sombre. Ils utilisaient une cinquantaine d'icônes, toutes implémentées avec <img src="/icons/whatever.svg">. Les icônes étaient noires. Quand ils ont mis en ligne le mode sombre, la panique s'est installée : les 50 icônes noires ont disparu sur le nouveau fond sombre. Leur premier « correctif » paniqué a été d'exporter un deuxième jeu d'icônes blanches (whatever-dark.svg) et d'écrire partout une logique conditionnelle bien dégueu (isDarkMode ? 'whatever-dark.svg' : 'whatever.svg'). C'était un enfer à maintenir.
Puis, un développeur a introduit un workflow de conversion SVG vers JSX. Ils ont lancé un script qui a converti les 50 SVG en composants React, en remplaçant de manière cruciale tous les attributs fill="black" par fill="currentColor". Ils ont remplacé toutes les balises <img> par leurs nouveaux composants d'icônes, comme <WhateverIcon />. Instantanément, les icônes ont hérité de la couleur de leur texte parent, qui était déjà gérée par le CSS du thème. Mode clair : texte noir, icônes noires. Mode sombre : texte blanc, icônes blanches. Ça a juste marché.
Leçon : Intégrer les SVG en tant que composants leur permet de s'intégrer de manière transparente avec le design system et le style existants de votre application, vous évitant ainsi l'enfer de la gestion d'assets.
La coche animée
Un product manager voulait une animation « charmante » : lorsqu'un utilisateur remplit un formulaire, une coche doit se dessiner dynamiquement à l'écran. Utiliser un GIF animé était hors de question — l'image était pixelisée et le fichier lourd. La développeuse a essayé de trouver une librairie, mais rien ne correspondait vraiment au design personnalisé de la coche.
Prenant les choses en main, elle a pris le SVG statique de la coche fourni par le designer et l'a converti en composant JSX. Cela lui a donné un accès direct à l'élément <path> de la coche dans son code React. En utilisant une simple transition CSS sur les propriétés stroke-dasharray et stroke-dashoffset de ce tracé, elle a pu créer l'effet de « dessin » exact qu'elle voulait. L'animation était parfaitement fluide, scalable à l'infini et ne pesait moins de 1 Ko de code.
Leçon : Convertir un SVG en composant débloque un contrôle granulaire sur ses parties individuelles, rendant possibles des animations complexes pilotées par CSS ou JavaScript.
Erreurs et pièges courants
- Oublier l'accessibilité. Une icône qui a un sens (comme un X pour « fermer ») n'est pas juste une décoration. Si vous supprimez la balise
<title>lors de la conversion, un lecteur d'écran pourrait l'annoncer comme « groupe » ou simplement l'ignorer. Assurez-vous toujours que votre composant final ait une proparia-labelappropriée ou un nom accessible via un élément<title>à l'intérieur du SVG. Un bon composant sera rendu comme<svg role="img" ...>. - Gonfler le bundle. Intégrer des SVG signifie que leur code fait maintenant partie de votre bundle JavaScript. Pour quelques dizaines de petites icônes d'UI, c'est un gain net (moins de requêtes HTTP). Mais si vous essayez d'intégrer une illustration énorme et complexe avec des milliers de tracés, vous pouvez sérieusement gonfler la taille de votre bundle et ralentir le chargement initial de la page. Pour les grandes illustrations statiques,
<img>reste un choix parfaitement valide. - Ignorer l'optimisation en amont. Les SVG exportés depuis des outils de design comme Figma ou Adobe Illustrator sont notoirement bordéliques. Ils contiennent des métadonnées de l'éditeur, des commentaires, des calques cachés et des valeurs décimales trop précises. Balancer ça directement dans un composant JSX donne un code lourd et difficile à lire. Passez toujours vos SVG dans un optimiseur comme SVGO avant de les convertir. Cela peut souvent réduire la taille du code de 50 % ou plus.
- L'édition manuelle devient un problème de synchro. Vous convertissez
icon.svgenIcon.jsx. Puis vous modifiez manuellementIcon.jsxpour ajouter une fonctionnalité. Une semaine plus tard, le designer vous donne une version mise à jour deicon.svg. Vous avez maintenant le choix : relancer la conversion et perdre vos modifications manuelles, ou essayer de patcher manuellement le nouveau design dans votre JSX modifié. La source de vérité devrait être le fichier.svg; la conversion en JSX devrait être un script répétable et automatisé.
Pourquoi vous devriez garder ça à l'œil
Vous devriez envisager de convertir les SVG en JSX chaque fois que vous construisez une application web à base de composants (React, Preact, etc.) et que vos icônes doivent être plus que de simples images statiques.
C'est le bon outil pour le travail quand :
- Vous avez besoin que les icônes changent de couleur, de taille ou d'épaisseur de trait en fonction de l'état ou des props.
- Vous construisez un design system ou une bibliothèque de composants et avez besoin d'un moyen scalable et cohérent de gérer les icônes.
- Vous voulez animer des parties d'une icône.
- Vous optimisez les performances et voulez réduire le nombre de requêtes réseau en intégrant (inlining) les icônes critiques.
Dans le développement frontend moderne, traiter vos icônes comme des composants n'est pas un hack — c'est la norme pour construire des interfaces utilisateur dynamiques, maintenables et performantes.
Pour aller plus loin
- MDN: SVG: Scalable Vector Graphics — Le guide ultime sur le fonctionnement du SVG dans le navigateur.
- W3C: Scalable Vector Graphics (SVG) 2 Specification — La spécification officielle. Dense, mais c'est la source de vérité ultime.
- React Docs: Forwarding Refs — La documentation officielle sur cette technique essentielle pour la composition de composants.
- MDN:
currentColor— La valeur CSS simple mais puissante qui fait du theming SVG un jeu d'enfant. - CSS-Tricks: Styling SVG — Une collection fantastique d'articles sur les nombreuses façons de manipuler et de styler les SVG avec du CSS.
- SVGO (SVG Optimizer) — L'outil de référence pour nettoyer les fichiers SVG. Comprendre ce qu'il fait vous fera apprécier ce qui constitue un composant SVG propre.