Chances are if you've ever used create-react-app
and you wanted to import an SVG file as a React component, you did something like this and it Just Worked™:
import { ReactComponent as Logo } from './logo.svg'
But, alas, if you have moved to using Vite more often, as I have, you can't just do that.
Never fear, it's still possible!
Enter vite-plugin-svgr
vite-plugin-svgr
is a Vite plugin to transform SVGs into React components! It's super intuitive to use:
npm install vite-plugin-svgr
Add it to your vite.config.js
:
import svgr from 'vite-plugin-svgr'export default { // ... plugins: [svgr()], // ...}
And boom, you get your expected behavior!
// somewhere in your React + Vite appimport { ReactComponent as WhateverIcon } from "./icons/WhateverIcon.svg";// ...export default function SomeComponent() { return ( <div> <WhateverIcon /> Wow, I love icons, because I am a dweeb </div> );}
This is particularly useful if you're using a library like MUI and you need to use a custom icon, like so:
// somewhere in your React + Vite appimport { Box, IconButton, SvgIcon } from "@mui/material";import { ReactComponent as WhateverIcon } from "./icons/WhateverIcon.svg";// ...export default function SomeComponent() { return ( <Box> <IconButton aria-label="some icon"> <SvgIcon> <WhateverIcon /> </SvgIcon> </IconButton> Wow, I love icons, because I am a dweeb </Box> );}
There's other things you can do with vite-plugin-svgr
, and there's a list of options here.
Hope that's helpful for ya, happy icon-ing!
Top comments (14)
Subscribe
Cooty
Cooty
Self-taught webdeveloper, jack of all trades, master of none. Passionate about making useful stuff for the Interwebz.
-
Work
Freelance webdeveloper
-
Joined
• Apr 10 '23
- Copy link
Nice one, works like a charm. I only have one small problem / question. I'm using TypeScript (v4.9.3), Vite v4.2.0 and vite-plugin-svgr v2.4.0.
I import icon as shown above:
import { ReactComponent as SunnyIcon } from '../assets/icons/sunny.svg'
I get a red underline for ReactComponent
saying:
Module '"*.svg"' has no exported member 'ReactComponent'. Did you mean to use 'import ReactComponent from "*.svg"' instead?ts(2614)
Of course if I use it as suggested, importing a default
import ReactComponent from '../assets/icons/sunny.svg'
the TS error goes away, but can't use it as a React component since this way I just get the asset path as string.
The quick solution that I've found is to add a // @ts-ignore
above it and move on with my life, but I wonder is there some way to get this working with TS?
moussaab moulim
moussaab moulim
-
Joined
• Apr 10 '23
- Copy link
check this answer stackoverflow.com/a/75818331/10251804
Christian GO
Christian GO
-
Location
Phoenix, AZ, USA
-
Joined
• Jan 7 '23
- Copy link
Informative, thank you for sharing!
Daniel Jimenez
Daniel Jimenez
-
Joined
• Mar 16 '23
- Copy link
Thank you so much for this! A great breakdown as I was able to set up the fix using this in a few seconds! Awesome stuff
Ahmad Adibzad
Ahmad Adibzad
Full-Stack Developer
-
Work
Developer
-
Joined
• Nov 19 '23
- Copy link
If you are using vite-plugin-svgr version ^4.0.0 make sure to use the '?react' suffix on your SVG file address:
import Logo from './logo.svg?react'
check out this:
stackoverflow.com/questions/70309561
José Pablo Ramírez Vargas
José Pablo Ramírez Vargas
-
Location
Heredia, Costa Rica
-
Work
Senior software developer @ Intel
-
Joined
• Jan 7 '23
- Copy link
Ok, serious question: I'm no Vite expert. I have only tested it a bit once. In the project, I have an SVG in the /assets
folder, react.svg
. It is imported from App.jsx
:
import reactLogo from './assets/react.svg'// Then used like this.<img src={reactLogo} className="logo react" alt="React logo" />
What's the difference in result between this and what you present? What is the gain?
Cassidy Williams
Cassidy Williams
bold and brash
-
Location
Chicago, IL
-
Education
B.S. Computer Science
-
Pronouns
she/her
-
Work
coding stuff
-
Joined
• Jan 9 '23
- Copy link
Long story short, by importing an SVG as a component, you can access the paths and objects in the component. If you use SVGs in <img>
tags, you don't get to control the innards of the SVG with CSS etc!
Md Kawsar Islam Yeasin
Md Kawsar Islam Yeasin
-
Location
Dhaka,Bangladesh
-
Joined
• Apr 3
- Copy link
If you use svgr then you don't need any Img tag.
basically, the svg will render in a img tag on the other hand if you use svgr then it will act like a native html svg elements. it's not like asserts that you have to load after the initial render.
It can render directly
Romanenko Serg
Romanenko Serg
-
Joined
• Feb 27 '23
- Copy link
In your case reactLogo use like url, so you can't do some SVG tricks, you can transform only img.
Leo santos
Leo santos
Passionate about tech and programming. Enjoy sharing skills and knowledge. In my free time, I learn new languages and explore interesting projects. 🚀
-
Work
Software Developer
-
Joined
• Jan 7 '23
- Copy link
This is interesting, Thank you!
Michael Luo
Michael Luo
-
Joined
• Sep 20 '23
- Copy link
How can I use svgr to import all the svg in the icons folder at once?
current progrewss
Hook
// hoos/useDynamicSvgImport.tsimport * as allIcons from '@/assets/images/icons';export function useDynamicSvgImport(iconName: string) { const SvgIcon = allIcons[iconName] || null; return { SvgIcon };}
Component
// components/SvgIcon.tsximport { useDynamicSvgImport } from "@/hooks/useDynamicSvgImport";interface IProps { iconName: string; wrapperStyle?: string; svgProp?: React.SVGProps<SVGSVGElement>;}function SvgIcon(props: IProps) { const { iconName, wrapperStyle, svgProp } = props; const { SvgIcon: RawSvgIcon } = useDynamicSvgImport(iconName); return ( <> {RawSvgIcon && ( <i className={wrapperStyle}> <RawSvgIcon {...svgProp} /> </i> )} </> );}export default SvgIcon;
Azaria Beryl
Azaria Beryl
A front-end developer who works with React.
-
Joined
• Jan 11 '23
- Copy link
I'm using React Icons and it works fine without this plugin. Have you tried it before?
Cassidy Williams
Cassidy Williams
bold and brash
-
Location
Chicago, IL
-
Education
B.S. Computer Science
-
Pronouns
she/her
-
Work
coding stuff
-
Joined
• Jan 11 '23
- Copy link
React Icons already exports SVGs as components. This is for your own custom SVG files that a designer might give to you, not from an existing library.
Azaria Beryl
Azaria Beryl
A front-end developer who works with React.
-
Joined
• Jan 11 '23 • Edited on Jan 11 • Edited
- Copy link
I see, that's why I never have problem with svg. Thanks
For further actions, you may consider blocking this person and/or reporting abuse