DEV Community

Cover image for Importing SVG files as React components with Vite
Cassidy Williams
Cassidy Williams

Posted on

 

Importing SVG files as React components with Vite

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'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Add it to your vite.config.js:

import svgr from 'vite-plugin-svgr'

export default {
  // ...
  plugins: [svgr()],
  // ...
}
Enter fullscreen mode Exit fullscreen mode

And boom, you get your expected behavior!

// somewhere in your React + Vite app

import { ReactComponent as WhateverIcon } from "./icons/WhateverIcon.svg";

// ...

export default function SomeComponent() {
    return (
        <div>
            <WhateverIcon />
            Wow, I love icons, because I am a dweeb
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

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 app

import { 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>
    );
}
Enter fullscreen mode Exit fullscreen mode

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 (9)

Collapse
 
christian_go3 profile image
Christian GO

Informative, thank you for sharing!

Collapse
 
danieljimenez0255 profile image
Daniel Jimenez

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

Collapse
 
leosantosw profile image
Leo santos

This is interesting, Thank you!

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

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" />
Enter fullscreen mode Exit fullscreen mode

What's the difference in result between this and what you present? What is the gain?

Collapse
 
cassidoo profile image
Cassidy Williams

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!

Collapse
 
seromaxa profile image
Romanenko Serg

In your case reactLogo use like url, so you can't do some SVG tricks, you can transform only img.

Collapse
 
azariaberyl profile image
Azaria Beryl Nagata

I'm using React Icons and it works fine without this plugin. Have you tried it before?

Collapse
 
cassidoo profile image
Cassidy Williams

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.

Collapse
 
azariaberyl profile image
Azaria Beryl Nagata • Edited

I see, that's why I never have problem with svg. Thanks

Does your company have something to share with DEV?

Create an Organization and start sharing content with the community on DEV.