React (Vite/Next) — Import Themable SVG Icons as Components

In modern React apps, the easiest way to use icons is to import SVG files as React components. In this guide, you’ll export minified SVGs from Axialis IconVectors with currentColor paints, set up SVGR for Vite/Next, and theme icons via CSS while keeping bundles small.
Export a clean, themable SVG from IconVectors
- Open or create your icon:
- File → Open… (Ctrl+O) or New Icon (Ctrl+N).
- Set fills/strokes to
currentColor
so the icon inherits CSS/text color in React.
Export a minified SVG via File → Export → Export Minified (Shift+Ctrl+M) to strip metadata and keep a clean viewBox
.
Vite (React + TypeScript): install & configure SVGR
- Install
npm i -D vite-plugin-svgr # or: pnpm add -D vite-plugin-svgr # or: yarn add -D vite-plugin-svgr
- Configure
vite.config.ts
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import svgr from 'vite-plugin-svgr' export default defineConfig({ plugins: [ react(), svgr({ svgrOptions: { // Keep viewBox for proper scaling; strip width/height svgo: true, svgoConfig: { plugins: [ { name: 'preset-default', params: { overrides: { removeViewBox: false } } }, 'removeDimensions' ] }, titleProp: true } }) ] })
- Add TypeScript types (project root)
// env.d.ts /// <reference types="vite/client" /> declare module '*.svg?react' { import * as React from 'react' const Component: React.FC<React.SVGProps<SVGSVGElement> & { title?: string }> export default Component }
- Import & use
import CheckIcon from './icons/check.svg?react' export function Button() { return ( <button className="inline-flex items-center gap-2 text-blue-600 hover:text-blue-700"> <CheckIcon className="w-5 h-5" aria-hidden="true" /> Save </button> ) }
Theming: Because your SVG uses
currentColor
, the icon adopts the button’s text color. AddclassName
orstyle={{ color: '#2563eb' }}
to change it.
Next.js: configure SVGR and import SVG components
- Install
npm i -D @svgr/webpack # (Next already includes SVGO; we'll keep viewBox and remove width/height)
- Configure
next.config.js
/** @type {import('next').NextConfig} */ const nextConfig = { webpack(config) { // Let SVGR handle .svg imports as React components config.module.rules.push({ test: /\.svg$/i, issuer: /\.[jt]sx?$/, use: [{ loader: '@svgr/webpack', options: { svgo: true, svgoConfig: { plugins: [ { name: 'preset-default', params: { overrides: { removeViewBox: false } } }, 'removeDimensions' ] }, titleProp: true } }] }) return config } } module.exports = nextConfig
- Add TypeScript types (project root)
// svg.d.ts declare module '*.svg' { import * as React from 'react' const Component: React.FC<React.SVGProps<SVGSVGElement> & { title?: string }> export default Component }
- Import & use
import CheckIcon from '@/icons/check.svg' export default function Page() { return ( <main className="p-6 text-emerald-600"> <h1 className="text-xl font-semibold flex items-center gap-2"> <CheckIcon className="w-6 h-6" aria-hidden="true" /> Profile updated </h1> </main> ) }
Tree‑shaking & project structure
- Import icons directly from files where they’re used (e.g.,
import Icon from './x.svg'
). Unused icons won’t be bundled. - Barrel files (
icons/index.ts
) can inhibit tree‑shaking if marked as side‑effectful. If you use a barrel, keep it pure or set"sideEffects": false
for the icons package. - Props: SVGR components accept standard
SVGProps<SVGSVGElement>
—passclassName
,title
,role
, etc.
Troubleshooting
- Icon won’t change color — ensure your SVG paths use
fill="currentColor"
/stroke="currentColor"
instead of hard‑coded hex colors. - ViewBox reset — keep
viewBox
by disabling SVGO’sremoveViewBox
and removing explicit width/height (shown in configs above). - Type errors — add the module declarations (
env.d.ts
/svg.d.ts
) as shown for Vite/Next TypeScript projects.
Start Making SVG Icons Today with IconVectors
Download the fully-functional 30‑Day Free Trial and unlock your icon design workflow.
Version 1.10 - September 17, 2025