There are two ways to display an SVG graphic on a webpage: by creating an img
tag that points to the SVG file, or by directly embedding the SVG code in the HTML. The latter method gives you more control over the SVG, and is particularly useful when you want to use CSS to change the color of the SVG.
To do this, you can use the currentColor
value in the SVG code, which allows the element to inherit the text color set by CSS. However, this technique only works if the SVG code is part of the DOM.
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="5" cy="5" r="5" fill="currentColor"/>
</svg>
I recently learned that it’s quite easy to embed SVG from a file in your React project.
If you import a SVG file most bundlers will return just a URL to the SVG file.
// Import
import svgIcon from './icon.svg'
// Usage in JSX
<img src={svgIcon} alt="Circle" />
But you can use SVGR to get the SVG markup into your DOM. SVGR is installed per default when using CRA, but there are also plugins for other tools.
// Import (SVGR has to be installed)
import { ReactComponent as SvgIcon } from './icon.svg'
// Usage in JSX
<SvgIcon />
// Usage with custom class and width
<SvgIcon className="my-class" width="42" />
Vite
While this works out of the box for Create React App projects, you need to install vite-plugin-svgr if you are using Vite.
// vite.config.js
import svgr from "vite-plugin-svgr";
export default {
// ...
plugins: [svgr(), react()],
};
If you are using typescript you might as well need to add the missing types in tsconfig.json:
"compilerOptions": {
...
"types": [
"vite-plugin-svgr/client"
]
}
Gatsby
And you can easily get this to work in Gatsby as well by installing this SVGR plugin for Gatsby.
npm install @svgr/webpack gatsby-plugin-svgr
Then add it to your Gatsby config:
// gatsby-config.js
module.exports = {
plugins: [
'gatsby-plugin-svgr',
],
}
That's it, you can now give classes to SVG elements, style them with CSS or use currentColor.
Here is the link to the CRA docs:
https://create-react-app.dev/docs/adding-images-fonts-and-files/#adding-svgs
Top comments (3)
Interesting! I’ve always been manually defining SVG colors, maybe it’s time for a change…
Disclaimer: This approach is really bad for browser cache. When you move svg source code to the DOM, you lose all the benefits of browser cache.
If you use SSR you should always have an eye on your document size. If it gets to large one thing to look out for are embedded images (Data URLs) or inline SVGs as you said. The same is true for the Javascript bundle size.
If you use React (without SSR) your code will be injected into the DOM via Javascript and the SVG data is inside your Javascript bundle that is cached by your browser.
Most of the time I use this feature for relatively small SVGs. For big SVG files features like currentColor are often not needed an it is better to use an
<img>
.But even then, some bundlers encode small images/svgs by default, so they would end up in your bundle anyway.