SVG to React: From Raw File to Production-Ready Component

SVG to React: From Raw File to Production-Ready Component

Convert SVG icons to React/JSX components, optimize them and ship in your design system.

21.07.2026
10 min read
Share this article:
SVG
react
jsx
frontend
components
Tutorial

Why move from raw SVG to a React component

Pasting inline SVG into JSX often breaks on the first build: HTML attributes (`class`, `stroke-width`) are invalid in React, embedded `<style>` tags are hard to maintain, and Figma exports bloat file size. The online SVG to JSX converter turns a `<svg>` file into a copy-ready React component — with attribute renames (`className`, `strokeWidth`), a custom component name, and an optional TypeScript mode. The full workflow runs in the browser on the online SVG tools hub, with no account or server upload. For optimization context, see also SVGO presets explained.

SVG → React function component in one step
SVG attributes mapped to JSX syntax (className, fillRule…)
Options: component name, default export, TypeScript
Optimize first with optimize-svg, then convert
100 % local processing — ideal for sensitive client assets

Example: UI icon in a design system

Before / after in the repo

A 24×24 icon exported from Figma may weigh 3–6 KB as raw SVG. After optimize default, often 1–2 KB. Generated JSX stays readable — use the <a href="/en/beautify-svg" class="text-primary hover:underline">online SVG beautifier</a> on intermediate markup if you need to audit paths.

Before optimization

File size:Source SVG ~4.8 KB
Load time:

After optimization

File size:optimize ~1.9 KB · JSX component ~2.1 KB
Load time:
Bundler impact (light context)

Each imported icon component lands in your app's JavaScript chunk — unlike a static `.svg` file. That's the usual React trade-off; the <a href="/en/minify-js" class="text-primary hover:underline">online JavaScript minifier</a> illustrates JS-side compression, but the first line of defense is a lean SVG source before conversion.

Best practices: props, className and accessibility

Styling with className and currentColor

The converter maps `class` → `className` and kebab-case SVG attributes to React camelCase. For consistent theming, edit source SVG or JSX to use `fill="currentColor"` and control color via CSS/Tailwind on the parent.

Prefer `currentColor` over fixed hex for UI icons
width/height → utility classes instead of fixed pixels
Spread props: `<svg {...props} className={cn('h-5 w-5', props.className)}>`
Don't rely on internal `<style>` — excluded from JSX
beautify-svg to read markup after manual edits
Accessibility: decorative vs informative

An icon beside visible text is decorative → `aria-hidden="true"` on `<svg>`. An icon that carries meaning (e.g. error status without text) needs `<title>` / `<desc>` or an explicit `aria-label`. FastMinify preserves title/desc on optimize; verify they survive conversion.

Decorative: `aria-hidden` + adjacent visible text
Informative: title/desc or aria-label on the component
validate-svg on source SVG before jsx
Upcoming article: SVG accessibility (SVG hub)
Don't remove viewBox — required for responsive scaling
Common pitfalls after conversion

Invalid component names (`icon-arrow`) → silent fallback to `SvgIcon` (the tool reports fallback). Invalid XML or multiple roots → parse error. Duplicate IDs if you inline the same component multiple times without a sprite.

Always PascalCase for componentName
Single root `<svg>` per file
Test render on the target page, not only Storybook
Version both source `.svg` and generated `.tsx`
Re-convert after each design change — don't hand-patch JSX

When the browser tool is enough

Common scenarios

No need to install SVGR to convert one icon from Slack or a one-off Figma export.

Prototype an icon component before adding to the repo
Unblock a front-end dev without Node / CI access
Compare generated JSX with an existing SVGR export
Train a designer on what ships to production
One-shot before a design system PR

Limits: SVGR and bundler plugins

What the browser does not replace

Online conversion is ideal to explore and ship a few components. Automatic `import Icon from './icon.svg'` on every build, batching an `icons/` folder, and custom SVGR templates remain the domain of `@svgr/cli`, `@svgr/webpack`, or `vite-plugin-svgr`.

Generate hundreds of components from an asset folder
Custom templates (memo, forwardRef, index barrel)
Pre-commit hook: svg → tsx on every change
Team config versioned in svgr.config.js
Plugins outside FastMinify options (inline svgo in SVGR)
Align browser preview and pipeline

Validate name, export, and JSX structure in svg-to-jsx, then mirror conventions in SVGR. Optimize with the same SVGO preset as CI — see <a href="/en/blog/svgo-presets-optimize-svg-web" class="text-primary hover:underline">SVGO presets</a> and the <a href="/en/blog/svg-optimization-guide-web" class="text-primary hover:underline">SVG optimization guide</a>.

Document componentName and export in icons README
Same optimize preset locally and in CI
Snapshot tests for critical icons
Don't mix hand-written and SVGR jsx without conventions
SVG hub as team tool reference

SVGR and the React ecosystem

Complementary tools

FastMinify svg-to-jsx covers paste → copy JSX with three options. The npm ecosystem offers more flexibility for automation.

@svgr/cli

SVGR command line — reference for batch and CI.

Pros:
Batch entire directories
Templates and `.svgrrc` config
Native pre-commit integration
Cons:
Node install required
Config/plugins learning curve

vite-plugin-svgr / @svgr/webpack

Import SVG as React component at compile time.

Pros:
Automatic on every import
Consistent with bundler workflow
No manual step for developers
Cons:
Less visible for comparing raw JSX
Harder conversion debug without an online tool

FastMinify optimize-svg + svg-to-jsx

Browser chain optimize → convert, no install.

Pros:
Privacy-local, zero config
Explicit componentName / TypeScript options
Perfect for one-shot and visual review
Cons:
No batch on hundreds of files
Manual edit for props spread and advanced a11y

Inline SVG, `<img>`, or React component?

Three ways to render SVG

The choice affects styling, accessibility, and JavaScript bundle size. A React component fits reusable icons in a design system; one-off inline or `<img src="icon.svg">` remains valid for simple cases.

Raw inline: fast but non-React attributes, hard to version
`<img>` / static asset: no `currentColor`, simple HTTP cache
React component: props, theming, bundler tree-shaking
`<symbol>` sprite: good for dozens of static icons
Component + SVGO optimize: best size / maintainability ratio
When a React component is worth it

UI icons (buttons, nav), themeable logos (`fill="currentColor"`), or assets shared across React/Next.js apps. The component encapsulates markup and avoids duplicating 200 lines of `<path>` on every page.

Design system with color / size variants
Animated or interactive icons (hover via className)
Internal `@company/icons` library
Storybook for isolated preview
Figma export → optimize → svg-to-jsx → PR
What conversion does not replace

svg-to-jsx produces JSX from existing markup. It does not resolve Sass `@use`, multi-file partials, or automatic generation on every commit — SVGR in CI still applies there. The online tool excels at prototyping, fixing an export, or onboarding a designer.

No `@import` resolution between SVG files
Embedded `<style>` tags are omitted from JSX output
Single root `<svg>` element required
Generated `props` param is not merged onto `<svg>` — manual edit if needed
Pair with validate-svg for title/desc before shipping

FastMinify workflow: optimize then svg-to-jsx

Step 1 — Clean and optimize the source SVG

An Illustrator or Figma export often carries metadata and excessive precision. Run the online SVGO optimizer first (safe or default preset for UI icons), or the SVG minifier for whitespace-only cleanup. You shrink the final component without changing the React workflow.

optimize-svg: safe / default / aggressive presets
minify-svg: whitespace and comments only
beautify-svg: read markup before conversion
Keep title/desc for informative icons
Compare before/after stats in the tool
Step 2 — Convert with svg-to-jsx

Paste the optimized SVG into the SVG to JSX tool. Pick the component name (must start with uppercase — otherwise falls back to `SvgIcon`), default vs named export, and TypeScript if your codebase uses `.tsx`.

componentName: e.g. `ChevronIcon`, `LogoMark`
exportDefault: `true` for default import, `false` for named export
typescript: adds `React.SVGProps` / `JSX.Element` annotations
Paste or load a file (limit shown in the tool)
Copy JSX and paste into your repo
Step 3 — Integrate into the design system

After copy, wrap as needed: merge `props` onto `<svg>` (`{...props}`), add `aria-hidden` for decorative icons, or `role="img"` + `aria-label` for informative ones. Validate with validate SVG online on source markup before conversion.

Spread `{...props}` on root `<svg>` for className/size
Replace fixed fill with `currentColor` for theming
Drop fixed width/height → CSS sizing (`className="h-5 w-5"`)
Test render in Storybook + visual snapshot
SVG hub for next steps (Data URI, viewer…)

Conclusion

The safest path to a maintainable React component: optimize the source SVG, convert to JSX with explicit options, then adjust props and accessibility in your design system. FastMinify chains optimize-svg and svg-to-jsx entirely in the browser — ideal to prototype before locking SVGR in CI.

Convert your SVG to a React component

Optimize (safe/default) before svg-to-jsx on Figma exports
PascalCase for componentName — avoid SvgIcon fallback
Merge props and aria on `<svg>` after copy
validate-svg for informative icons
SVGR in CI once the component is validated in the browser
Share this article
Share this article: