SVG 转 JSX 转换器

在浏览器中即时将 SVG 转换为 React JSX 组件,自动处理驼峰属性、className,支持 TypeScript、forwardRef 和 memo 包裹。免费无需注册。

  • 在浏览器中处理
  • 数据不离开你的设备
  • 免费 · 无需注册
默认为 MyIcon。生成的名称只保留 ASCII 字母、数字、_ 和 $;开头的小写 ASCII 字母改为大写。编辑后等待 200 毫秒转换。
添加 SVG 属性类型。未勾选 forwardRef 时使用 React.FC;勾选时为 forwardRef 添加 SVG 元素与属性的泛型。切换后立即转换。
用 forwardRef 包裹组件,并在第一个 svg 元素的展开 props 之前添加 ref={ref}。切换后立即转换。
用 memo 包裹默认导出。切换后立即转换。
复制完整显示的组件。输出为空时不复制。

每次粘贴一个 SVG 图标。输入变化后等待 200 毫秒转换,只有第一个 svg 元素获得展开的 props。焦点在工具内时,Ctrl/⌘+L 清空文本字段与状态。
使用前检查生成的组件。无法保留的样式会清空输出并停用复制;状态栏给出位置与原因。
示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。

属性转换规则

SVGJSX
stroke-widthstrokeWidth
stroke-linecapstrokeLinecap
fill-rulefillRule
clip-pathclipPath
classclassName
font-sizefontSize
text-anchortextAnchor
xmlns="..."(已移除)

输出模式

  • 默认:无 TypeScript 注解的普通函数组件。
  • TypeScript:添加 React.FC<React.SVGProps<SVGSVGElement>> 类型,支持 className、style、onClick 等 prop。
  • forwardRef:将组件包裹在 React.forwardRef 中,向父组件暴露 SVG 元素的 ref。
  • memo:将最终导出包裹在 React.memo 中,跳过不必要的重新渲染。

常见使用场景

  • 将 Figma 或 Illustrator 导出的 SVG 转换为 React 图标组件
  • 将 SVG 图标库迁移到基于 JSX 的设计系统
  • 让 SVG 图标接受 className、style 等 React props
  • 构建通过展开 props 接受 aria-label 的无障碍图标组件

示例

一个 24 × 24 的加号图标,组件名填 PlusIcon,三个选项都不勾:

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="#000" stroke-width="2" stroke-linecap="round" d="M12 5v14M5 12h14"/></svg>

输出:

import React from 'react';

function PlusIcon(props) {
  return (
    <svg width="24" height="24" fill="none" viewBox="0 0 24 24" {...props}><path stroke="#000" strokeWidth="2" strokeLinecap="round" d="M12 5v14M5 12h14" /></svg>
  );
}

export default PlusIcon;

xmlns 被删掉,stroke-width、stroke-linecap 改成驼峰,其余标记原样保留。{...props} 放在根元素自身属性之后,与 svgr 的默认值(expandProps: 'end')位置相同,调用方传的值优先:<PlusIcon width={48} fill="red" /> 渲染成 48 px、红色,height 仍是 24。属性值仍是字符串(strokeWidth="2"),React 字符串和数字都接受。TypeScript、forwardRef、memo 全勾时,同一图标输出为 const PlusIcon = forwardRef<SVGSVGElement, React.SVGProps<SVGSVGElement>>(function PlusIcon(props, ref) { ... }),<svg> 自身属性之后是 ref={ref} {...props},末尾 export default memo(PlusIcon);。React 19 起不再需要 forwardRef,函数组件可以直接把 ref 当作 prop 接收。

Illustrator 用 Internal CSS 导出、带内联 style 与 xlink:href 的图标,组件名 Icon:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><!-- Generator: Adobe Illustrator --><defs><style>.cls-1{fill:#e11d48;}</style></defs><path id="a" class="cls-1" style="stroke:#000;stroke-width:2" d="M12 5v14"/><use xlink:href="#a"/></svg>

输出:

import React from 'react';

function Icon(props) {
  return (
    <svg viewBox="0 0 24 24" {...props}>{/* Generator: Adobe Illustrator */}<defs><style>{".cls-1{fill:#e11d48;}"}</style></defs><path id="a" className="cls-1" style={{ "stroke": "#000", "strokeWidth": "2" }} d="M12 5v14" /><use xlinkHref="#a" /></svg>
  );
}

export default Icon;

注释变成 {/* ... */},React 不会渲染它。<style> 里的 CSS 变成一个 JavaScript 字符串,其中的花括号不再被当作 JSX;里面的实体会被解码,<![CDATA[ ... ]]> 外壳会被去掉。style 属性变成对象,值按原文复制;xlink:href 变成 xlinkHref。用 esbuild 0.21.5 编译、React 19.2.0 开发版渲染,结果是 <svg viewBox="0 0 24 24"><defs><style>.cls-1{fill:#e11d48;}</style></defs><path id="a" class="cls-1" style="stroke:#000;stroke-width:2" d="M12 5v14"></path><use xlink:href="#a"></use></svg>,控制台没有警告。

粘贴前:导出设置

  • Figma:选中图层 → Export → SVG。除非要按 ID 操作元素,否则不勾「Include “id” attribute」。
  • Illustrator:File → Export → Export As → SVG(菜单名按英文界面)。Styling 选 Presentation Attributes 得到的组件最短。Internal CSS、Inline Style 会生成 <style> 块或 style="..." 字符串(Adobe:SVG 导出选项),本工具会把它们转成 CSS 字符串和样式对象,见上例。<style> 块对整个页面生效,两个图标都用 .cls-1 时会互相改颜色。
  • 工具会去掉 <?xml ... ?> 声明,并把注释转成 JSX 注释,<!-- Generator: ... --> 不必先删。

仍需手动修改的地方

下表每一行都用 esbuild 0.21.5 编译输出、再用 React 19.2.0 渲染核对过。

粘贴的 SVG 里工具输出在 React 中的结果改成
style="fill:red !important"、同一属性写两次、style 里有 CSS 注释无输出:拒绝转换、停用复制,状态栏给出样式中的位置—把规则移到 <style> 块或 CSS 文件里,或去掉 !important
<text>{count}</text><text>&#123;count&#125;</text>显示文字 {count}想用变量就自己改成 {count}
写死的 fill / stroke 颜色原样保留图标不跟随文字颜色fill="currentColor" / stroke="currentColor"
<style> 里的类名和其他图标重复CSS 字符串规则对整个页面生效改类名,或用 Presentation Attributes 导出

限制

  • 用正则匹配,不是 XML 解析器:先识别注释、<style> 块和 CDATA,所以写在 <!-- ... --> 里的标签不会被转换。带引号的属性值里可以有 > 和 /。不会补全未闭合的标签。
  • 值按原文复制:只改属性名,aria-label="class schedule" 仍是 aria-label="class schedule"。例外是 style(变成对象)和文字:文字里的 {、}、<、> 写成 &#123;、&#125;、&lt;、&gt;,React 显示的仍是原字符。
  • React 对象无法保留的样式会被拒绝:style 属性里有 !important、同一属性写两次(CSS 回退)、CSS 注释、含转义的属性名、未闭合的引号或括号时停止转换,清空输出并停用复制,直到输入改变。
  • 一次一个组件:只有第一个 <svg> 会加 {...props},雪碧图请逐个图标粘贴。
  • 组件名:字母、数字、_、$ 以外的字符会被删掉,首字母自动大写(plus-icon → Plusicon)。中文组件名会被整段删掉,回退为 MyIcon。
  • data-* 与 aria-* 属性保留连字符,这也是 React 的要求。

FAQ

SVG 转 JSX 工具做什么?

它将原始 SVG 文件转换为可复用的 React 组件。主要变更包括:将连字符属性转为驼峰命名(stroke-width → strokeWidth)、将 class 重命名为 className、移除 xmlns 声明,并将 SVG 标记包裹在函数组件中。

为什么要重命名 SVG 属性?

JSX 会被编译为 JavaScript,连字符属性名不是合法的 JS 标识符。React 要求使用驼峰命名版本,如 strokeWidth、fillRule、clipPath 等。

TypeScript 选项有什么作用?

启用后,输出使用 React.FC<React.SVGProps<SVGSVGElement>> 作为组件类型,提供完整的 TypeScript 支持,包括 SVG 属性的自动补全。

forwardRef 有什么用?

forwardRef 允许父组件将 ref 附加到底层 SVG 元素,适用于需要以编程方式访问 DOM 节点的场景,例如测量尺寸或触发动画。

memo 包裹有什么作用?

React.memo 包裹组件,使其仅在 props 变化时才重新渲染,是图标组件的性能优化手段。

数据会发送到服务器吗?

不会。转换在浏览器中通过 JavaScript 运行,不传输任何 SVG 数据。