Em uma frase
SVG para JSX transforma o código da sua imagem vetorial em um componente React reutilizável, tornando-o dinâmico e controlável com props, em vez de ser apenas um arquivo estático.
O problema que ele resolve
Nos primórdios da web (tipo, uns cinco anos atrás), se você quisesse exibir um ícone SVG, provavelmente apenas o jogaria numa tag <img>: <img src="/icons/user.svg" alt="User profile" />. Trabalho feito. Pode subir pra produção.
Mas essa abordagem simples é uma bela de uma cilada. Seu SVG agora é uma caixa preta. Quer mudar a cor dele quando o usuário passa o mouse sobre o botão que o contém? Azar o seu. O navegador o trata como qualquer outro arquivo de imagem (um JPG, um PNG), e você não pode estilizar suas entranhas facilmente com CSS. Quer animar um dos paths dentro do ícone? Nem pensar. Quer trocar a cor para um tema de modo escuro? Você vai ter que criar um arquivo totalmente novo (user-white.svg) e escrever lógica para trocar o src. A coisa complica rápido.
"Aha!" diz o dev espertinho. "SVG é apenas código XML! Vou simplesmente copiar o código do arquivo .svg e colar direto no return do meu componente!"
// MyComponent.js
const MyComponent = () => (
<div>
<p>My Profile</p>
{/* Acabei de colar isso de um arquivo .svg! */}
<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>
);
Isso é chamado de "inlining", e é um passo gigantesco. Agora o SVG faz parte do DOM, e você pode estilizá-lo com CSS. Mas você trocou um problema por outro.
- É Tosco: Aquele blocão de código SVG torna seu componente mais difícil de ler. Imagine se você tivesse cinco ícones ali.
- Não é Reutilizável: Precisa daquele ícone de usuário em outro lugar? Prepare-se para copiar e colar aquele blocão inteiro de novo e de novo.
- Não é JSX: O React tem seu próprio dialeto de HTML. Atributos como
stroke-widthprecisam ser convertidos para camelCase, virandostrokeWidth, eclassse tornaclassName. Esquecer de converter isso pode levar a falhas silenciosas ou warnings barulhentos no console.
A verdadeira solução é tratar os ícones não como assets estáticos, mas como cidadãos de primeira classe do seu ecossistema de componentes. Você quer <UserIcon color="blue" size={24} />. Este é o problema que a conversão de SVG para JSX resolve: ela automatiza o boilerplate de transformar código SVG bruto em um componente React limpo, reutilizável e controlado por props.
Como funciona por debaixo dos panos
Transformar um monte de texto em um componente React elegante pode parecer mágica, mas é um processo previsível, passo a passo. Vamos dar uma espiada nos bastidores.
Passo 1: Analisando o Código SVG
Primeiro, a ferramenta precisa entender o SVG. Como SVG é um dialeto de XML, ele pode ser "parseado" (analisado) em uma estrutura de árvore de nós (nodes), assim como um documento HTML. Cada elemento (<svg>, <path>, <g>, etc.) se torna um nó, e seus atributos (width, fill, d, etc.) se tornam propriedades desse nó.
Então, isto:
<svg width="24" height="24">
<path fill-rule="evenodd" d="..." />
</svg>
É entendido pelo parser como uma árvore:
- nó
svgcom atributoswidth="24"eheight="24"- nó
pathcom atributosfill-rule="evenodd"ed="..."
- nó
Passo 2: "JSX-ificando" os Atributos
É aqui que a tradução específica para React acontece. O parser percorre a árvore de nós e converte os atributos para serem compatíveis com JSX.
- Camel-casing: Qualquer atributo com um hífen (kebab-case) é convertido para camelCase.
fill-rulese tornafillRule,stroke-widthse tornastrokeWidth. - Mapeamento de palavras-chave: Palavras-chave reservadas do JavaScript são trocadas. A mais comum é
class, que se tornaclassName. - Atributos de estilo: Um atributo
style="fill:red; stroke:blue"é convertido em um objeto JavaScript:style={{ fill: 'red', stroke: 'blue' }}.
Então, <path fill-rule="evenodd" class="icon-path"> se transforma no equivalente JSX: <path fillRule="evenodd" className="icon-path">.
Passo 3: Envelopando em um Componente
Com a árvore SVG agora falando JSX fluente, o próximo passo é envolvê-la em uma estrutura padrão de componente funcional do React. A versão mais simples se parece com isto:
import React from 'react';
const MyIcon = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24">
{/* ... todos os paths e outros elementos JSX-ificados ... */}
</svg>
);
};
export default MyIcon;
Isso já te dá um componente <MyIcon /> reutilizável, o que é uma grande vitória. Mas o verdadeiro poder vem de torná-lo dinâmico.
Passo 4: Adicionando Props e currentColor
Este é o pulo do gato. Um bom conversor não apenas deixa os atributos originais do SVG fixos no código. Ele os torna configuráveis.
Espalhando Props (Spreading Props): O componente é modificado para aceitar props e espalhá-las no elemento
<svg>raiz. Isso é frequentemente feito usando a sintaxe...rest. Agora você pode passar qualquer atributo SVG padrão (comowidth,height,classNameouaria-label) diretamente para o seu componente.O Truque do
currentColor: Isso é um divisor de águas para estilização. O conversor encontrará atributosfillestrokecom valores fixos que definem a cor do ícone (ex:fill="#000000") e os substituirá pela palavra-chave especial do CSScurrentColor.
currentColor diz ao navegador: "Qualquer que seja a propriedade CSS color neste elemento, use-a para o fill/stroke." Isso significa que seu ícone agora se comporta como texto. Se você envolver seu ícone em uma div e definir color: blue, o ícone fica azul.
// O componente turbinado
const MyIcon = ({ color = 'currentColor', size = 24, ...rest }) => {
return (
<svg
width={size}
height={size}
fill={color} // ou aplicado diretamente aos paths
{...rest}
>
<path d="..." fill="currentColor" />
</svg>
);
};
Passo 5: Encaminhando Refs (Forwarding Refs)
Às vezes, você precisa de um acesso direto ao elemento DOM <svg> real a partir de um componente pai, talvez para medir sua posição ou usá-lo com uma biblioteca de terceiros. Um componente funcional normal esconde sua estrutura interna do DOM. A solução é o React.forwardRef.
Um conversor sofisticado envolverá o componente em React.forwardRef, que cria um canal para passar uma ref do pai diretamente para a tag <svg> subjacente.
O componente final, de nível de produção, geralmente se parece com algo assim (exemplo em 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'; // Bom para debugar
export default MyIcon;
Histórias do mundo real
O Pesadelo da Tematização
Uma equipe de frontend estava construindo uma bela aplicação web que tinha tanto um modo claro quanto um modo escuro. Eles usavam cerca de 50 ícones, todos implementados como <img src="/icons/whatever.svg">. Os ícones eram pretos. Quando lançaram o modo escuro, o pânico se instalou: todos os 50 ícones pretos desapareceram contra o novo fundo escuro. A primeira "solução" desesperada foi exportar um segundo conjunto de ícones brancos (whatever-dark.svg) e escrever uma lógica condicional medonha (isDarkMode ? 'whatever-dark.svg' : 'whatever.svg') em todos os lugares. Foi um desastre de manutenção.
Então, um desenvolvedor introduziu um workflow de SVG-para-JSX. Eles rodaram um script que converteu todos os 50 SVGs em componentes React, substituindo crucialmente todos os atributos fill="black" por fill="currentColor". Eles substituíram todas as tags <img> por seus novos componentes de ícone, como <WhateverIcon />. Instantaneamente, os ícones herdaram sua cor da cor do texto do elemento pai, que já era tratada pelo CSS do tema. Modo claro: texto preto, ícones pretos. Modo escuro: texto branco, ícones brancos. Simplesmente funcionou.
Lição: Fazer o "inlining" de SVGs como componentes permite que eles se integrem perfeitamente com o design system e a estilização existentes da sua aplicação, salvando você do inferno de gerenciamento de assets.
O Checkmark Animado
Um gerente de produto queria uma animação "delightful": quando um usuário completa um formulário, um checkmark deveria se desenhar dinamicamente na tela. Usar um GIF animado estava fora de questão — ficava pixelado e era um arquivo pesado. A desenvolvedora tentou encontrar uma biblioteca, mas nada se encaixava perfeitamente no design personalizado do checkmark.
Tomando as rédeas da situação, ela pegou o SVG estático do checkmark fornecido pelo designer e o converteu em um componente JSX. Isso lhe deu acesso direto ao elemento <path> do checkmark dentro do seu código React. Usando uma simples transição de CSS nas propriedades stroke-dasharray e stroke-dashoffset daquele path, ela conseguiu criar o efeito exato de "desenho" que queria. A animação ficou super fluida, infinitamente escalável e ocupou menos de 1KB de código.
Lição: Converter um SVG para um componente desbloqueia um controle granular sobre suas partes individuais, tornando possíveis animações complexas com CSS ou JavaScript.
Erros e armadilhas comuns
- Esquecer da acessibilidade. Um ícone que transmite significado (como um X de "fechar") não é apenas decoração. Se você remover a tag
<title>durante a conversão, um leitor de tela pode anunciá-lo como "grupo" ou simplesmente ignorá-lo. Sempre garanta que seu componente final tenha uma proparia-labelapropriada ou um nome acessível por meio de um elemento<title>dentro do SVG. Um bom componente será renderizado como<svg role="img" ...>. - Inchando o bundle. Fazer "inlining" de SVGs significa que o código deles agora faz parte do seu bundle JavaScript. Para algumas dezenas de pequenos ícones de UI, o saldo é positivo (menos requisições HTTP). Mas se você tentar fazer inlining de uma ilustração enorme e complexa com milhares de paths, pode inchar seriamente o tamanho do seu bundle e retardar o carregamento inicial da página. Para ilustrações grandes e estáticas,
<img>ainda é uma escolha perfeitamente válida. - Ignorar a otimização primeiro. SVGs exportados de ferramentas de design como Figma ou Adobe Illustrator são notoriamente bagunçados. Eles contêm metadados do editor, comentários, camadas ocultas e valores decimais excessivamente precisos. Empurrar isso diretamente para um componente JSX resulta em código inchado e difícil de ler. Sempre passe seus SVGs por um otimizador como o SVGO antes de convertê-los. Isso muitas vezes pode reduzir o tamanho do código em 50% ou mais.
- Edição manual se torna um problema de sincronia. Você converte
icon.svgparaIcon.jsx. Então você mexe manualmente emIcon.jsxpara adicionar um recurso. Uma semana depois, o designer te entrega umicon.svgatualizado. Agora você tem uma escolha: rodar a conversão novamente e perder suas edições manuais, ou tentar aplicar manualmente o novo design no seu JSX editado. A fonte da verdade deve ser o arquivo.svg; a conversão para JSX deve ser um script repetível e automatizado.
Por que isso deve estar no seu radar
Você deve pensar em converter SVGs para JSX sempre que estiver construindo uma aplicação web baseada em componentes (React, Preact, etc.) e seus ícones precisarem ser mais do que apenas imagens estáticas.
É a ferramenta certa para o trabalho quando:
- Você precisa que os ícones mudem de cor, tamanho ou espessura do traço com base em estado ou props.
- Você está construindo um design system ou uma biblioteca de componentes e precisa de uma maneira escalável e consistente para gerenciar ícones.
- Você quer animar partes de um ícone.
- Você está otimizando a performance e quer reduzir o número de requisições de rede fazendo o "inlining" de ícones críticos.
No desenvolvimento frontend moderno, tratar seus ícones como componentes não é uma gambiarra — é o padrão para construir interfaces de usuário dinâmicas, de fácil manutenção e de alta performance.
Aprofunde-se
- MDN: SVG: Scalable Vector Graphics — O guia definitivo de como SVG funciona no navegador.
- W3C: Scalable Vector Graphics (SVG) 2 Specification — A especificação oficial. Densa, mas a fonte da verdade suprema.
- React Docs: Forwarding Refs — A documentação oficial sobre esta técnica essencial para composição de componentes.
- MDN:
currentColor— O valor CSS simples, mas poderoso, que torna a tematização de SVGs uma moleza. - CSS-Tricks: Styling SVG — Uma fantástica coleção de artigos sobre as muitas maneiras de manipular e estilizar SVGs com CSS.
- SVGO (SVG Optimizer) — A ferramenta padrão da indústria para limpar arquivos SVG. Entender o que ela faz fará você apreciar o que entra em um componente SVG limpo.