FigmaからエクスポートしたSVGをReactコンポーネントに貼り付けると、ほぼ必ずエラーが出ます。stroke-widthはJSXで無効な属性名であり、classはJavaScriptの予約語と衝突し、xmlns:xlinkの宣言は警告を出します。SVGをJSXへ手動変換するのは手間がかかり、ミスも起きやすい作業です。このガイドでは全ての変換ルールを解説した後、SVG to JSXコンバーターで一発解決する方法を紹介します。
生のSVGがReactで動かない理由
SVGマークアップはXML属性命名規則を使います。JSXはコンパイルされるJavaScriptです。Reactコンポーネントの中で両者が混在すると、いくつかの問題が起きます:
stroke-width、fill-opacity、stroke-linecapのようなハイフン属性はJavaScript識別子として無効です。JSXはcamelCaseを要求します:strokeWidth、fillOpacity、strokeLinecap。class属性はJavaScriptのclassキーワードと衝突するためclassNameにする必要があります。xmlnsとxmlns:xlinkの宣言はReactコンポーネントツリー内では不要で、コンソール警告を発生させます。- **
xlink:href**はSVG 1.1のレガシー属性です。現代のSVGとJSXではhrefを使います。 - style属性 — インラインの
style="fill: red"はJSXオブジェクト形式style={{ fill: 'red' }}にする必要があります。
SVG属性変換対照表
| SVG / HTML | JSX | 備考 |
|---|---|---|
stroke-width="2" | strokeWidth={2} | camelCase |
fill-opacity="0.5" | fillOpacity={0.5} | camelCase |
stroke-linecap="round" | strokeLinecap="round" | camelCase |
stroke-linejoin="round" | strokeLinejoin="round" | camelCase |
stroke-dasharray="4 2" | strokeDasharray="4 2" | camelCase |
clip-path="url(#c)" | clipPath="url(#c)" | camelCase |
fill-rule="evenodd" | fillRule="evenodd" | camelCase |
clip-rule="evenodd" | clipRule="evenodd" | camelCase |
color-interpolation-filters | colorInterpolationFilters | camelCase |
class="icon" | className="icon" | JS予約語 |
xlink:href="#id" | href="#id" | レガシー属性を削除 |
xmlns:xlink="..." | (削除) | JSX内で不要 |
style="fill:red" | style={{ fill: 'red' }} | JSオブジェクト |
tabindex="0" | tabIndex={0} | camelCase+数値 |
viewBoxは変更なし — すでにcamelCase互換で、Reactがそのまま受け付けます。
data-*とaria-*属性 — HTMLと同様、JSXでもハイフン区切りのままで、camelCaseにしません。
SVGをReactコンポーネントとしてラップする
属性を修正したら、SVGにコンポーネントの外殻が必要です。最小構成:
export function IconStar() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={24}
height={24}
fill="currentColor"
>
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87..." />
</svg>
);
}
propsスプレッドで柔軟性を持たせる
本番のアイコンコンポーネントはclassName、aria-label、onClick、カスタムのwidth/heightなど任意のpropsを受け取れるようにすべきです:
export function IconStar(props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={24}
height={24}
fill="currentColor"
{...props}
>
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87..." />
</svg>
);
}
TypeScriptバージョン
TypeScriptではReact.SVGProps<SVGSVGElement>を使うと呼び出し元で完全な型推論が得られます:
import type { SVGProps } from 'react';
export function IconStar(props: SVGProps<SVGSVGElement>) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={24}
height={24}
fill="currentColor"
{...props}
>
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87..." />
</svg>
);
}
forwardRefバージョン
アニメーション・寸法計測・フォーカス管理のためにSVG要素にDOM refを付けたい場合はforwardRefを使います:
import { forwardRef } from 'react';
import type { SVGProps, Ref } from 'react';
export const IconStar = forwardRef(
(props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
<svg
ref={ref}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={24}
height={24}
fill="currentColor"
{...props}
>
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87..." />
</svg>
)
);
IconStar.displayName = 'IconStar';
よくあるワークフロー
Figmaからのエクスポート
- Figmaでベクターレイヤーまたはコンポーネントを選択します。
- 右パネル → Export → SVGを選択。
- アニメーションでid参照が必要な場合のみInclude “id” Attributeをチェック、それ以外はオフ。
- エクスポートしたSVGマークアップをコピー。
- SVG to JSXコンバーターに貼り付けてReactコンポーネント出力をコピー。
FigmaのSVGはパスにfill="black"が含まれることが多いです。親要素のテキストカラーを継承させたい場合は、ハードコードされたfill値をfill="currentColor"に置き換えるか、コンバーターのオプションで設定してください。
Adobe Illustratorからのエクスポート
- ファイル → 書き出し → 書き出し形式 → SVG。
- SVGオプションでスタイルをプレゼンテーション属性に設定(CSSは
<style>ブロックを生成して変換が難しくなるため避ける)。 - SVGソースをコピーしてコンバーターに貼り付け。
Illustratorの出力にはよく<defs>とグラデーション定義が含まれます。コンバーターはこれらの構造を保持しながら全属性名を修正します。
複数パスのSVGの処理
複雑なアイコンには<path>・<circle>・<rect>・<g>が複数含まれます。コンバーターはSVGツリー全体を処理し、ルート要素だけでなくすべての子要素の全属性を正しく変換します。
<!-- 入力SVG -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g fill="none" stroke-width="1.5" stroke="currentColor">
<circle cx="12" cy="12" r="10"/>
<path stroke-linecap="round" d="M8 12h8M12 8v8"/>
</g>
</svg>
// 出力JSXコンポーネント
export function IconCirclePlus(props) {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" {...props}>
<g fill="none" strokeWidth={1.5} stroke="currentColor">
<circle cx={12} cy={12} r={10} />
<path strokeLinecap="round" d="M8 12h8M12 8v8" />
</g>
</svg>
);
}
プライバシーとセキュリティ
zerotool.devのSVG to JSXコンバーターは完全にブラウザ内で動作します。SVGコードはサーバーに送信されません。未公開のプロダクトアイコンや独自デザインシステムのアセットを扱うチームにとって重要な点で、変換はローカルで完結し、データは一切外部に出ません。
オンラインSVG to JSXコンバーター
ZeroToolのSVG to JSXコンバーターは上記の全ルールをワンペーストで処理します:
- ハイフン付きSVG属性をcamelCaseに変換
classをclassNameに置換xmlns:xlinkを削除しxlink:hrefをhrefに書き換え- 関数コンポーネントとして出力をラップ
- TypeScript型(
SVGProps<SVGSVGElement>)のオプション対応 forwardRefラッパーのオプション対応- ルート要素への
{...props}スプレッドのオプション対応
SVG以外のHTMLをJSXに変換する場合はHTML to JSXコンバーターをご利用ください。