Nedy Udombat Software engineer.

How to use SVGs in React

6 min read 1762

What is an SVG?

SVG is a vector graphics image format based on XML. SVG stands for Scalable Vector Graphics. It was developed in the late 1990s and was poorly supported until around 2016.

Today, a huge percentage of icon libraries, such as Flaticon, Font Awesome, Material Icon, etc., have full support for SVG. Brands such as Twitter, YouTube, Udacity, Netflix, and more use SVG for some of their images and icons.

Why use SVG over other image formats?

You’re probably more familiar with image formats like JPEG, GIFs, and PNG than you are with SVG. Let’s start by taking a look at some of SVG’s advantages over other image formats.

  • Scalability and resolution: This is the utmost advantage of SVG over other formats. SVG uses shapes, numbers, and coordinates instead of pixel grids like other image formats do. This makes it possible to zoom in and out of SVG images without losing quality and gives SVG the ability to scale infinitely
  • Small file size: SVG file sizes are usually small compared to other file formats, and they are easily compressible, which allows for their sizes to be even smaller
  • High performance and speed: Because of their small size, SVG images are very easy and fast for browsers to render. It’s like rendering text compared to rendering pixels and colors for other image formats. Also, if you use inline SVG in your code, the browser does not have to make a request to get the image and renders it just like all the other code in your file. In this case, no request was made. But in a situation where you have a complex image SVG file, such as the Mona Lisa photo, I would suggest using PNGs or JPEGs as the load time and performance for SVGs can fall drastically
  • DOM-like, style-able, and editable: SVG images are like code, so this means it can be navigated like a DOM element and also styled. Some properties will have different names, however: you might want to use fill instead of color, for example. You can also style SVG with CSS. Likewise, because SVGs are DOM-like, SVGs can be created, edited, and animated with any text editor
  • Animatable: SVGs can be animated. This can be done with tools like Web Animation APIs, WebGL, CSS animations, etc. Read more about animating SVG with CSS in this detailed post by Hope Armstrong
  • Ease of integration: SVGs can be used in various ways: they can display logo images and icons, graphs, animations, effects, and more
  • Accessibility and SEO: SVGs contain text, which improves accessibility. It also means they can be searched, indexed, scripted, etc.

How to use SVGs in React

svg react example

Below we’ll go through various ways we can use or render this React SVG logo on a webpage.

Using the <img> tag for static SVGs

In order to use SVGs or any other image format in the <img> tag, we have to set up a file loader system in whichever module bundler we’re using. Here, I will show you how to set it up in a few steps if you are already using webpack as your bundler.

First, install the file-loader library with the command $ npm install file-loader --save-dev. This will install it as a dev dependency.

You can update your webpack configuration file rules with this code:

const webpack = require('webpack');

module.exports = {
  entry: './src/index.js',
  module: {
    rules: [
      //...
      {
        test: /\.(png|jp(e*)g|svg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'images/[hash]-[name].[ext]',
            },
          },
        ],
      },
    ],
  },
  //...
};

Now you can import your SVG and use it as a variable, like this:

import React from 'react';
{/*images*/}
import ReactLogo from './logo.svg';

const App = () => {
  return (
    <div className="App">
      <img src={ReactLogo} alt="React Logo" />
    </div>
  );
}
export default App;

Using the <svg> element

With the same webpack settings above, we can use the <svg> element by basically copying and pasting the contents of the .svg file into our code. Here is a sample use case:

import React from 'react';

const App = () => {
  return (
    <div className="App">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
        <g fill="#61DAFB">
          <path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
          <circle cx="420.9" cy="296.5" r="45.7"/>
          <path d="M520.5 78.1z"/>
        </g>
      </svg>
    </div>
  );
}
export default App;

You can likely already see the disadvantage of using this method. When the image is more complex, the SVG file becomes larger, and since SVG is stored in text, that means we have a whole bunch of text in our code.

Using an SVG as a component

SVGs can be imported and used directly as a React component in your React code. The image is not loaded as a separate file; rather, it’s rendered along with the HTML. A sample use case would look like this:

import React from 'react';
import {ReactComponent as ReactLogo} from './logo.svg';

const App = () => {
  return (
    <div className="App">
      <ReactLogo />
    </div>
  );
}
export default App;

Note that this approach only works with Create React App. CRA uses SVGR under the hood to make it possible to transform and import an SVG as a React component. If you’re not using Create React App, I would recommend using other approaches.

Using SVGR

SVGR is an awesome tool that converts your SVGs into React components. So how do we set it up?

First, install the package by running the command $ npm install @svgr/webpack --save-dev. Then, update your webpack configuration rule to use SVGR for SVGs:

const webpack = require('webpack');

module.exports = {
  entry: './src/index.js',
  module: {
    rules: [
      //...
      {
        test: /\.svg$/,
        use: ['@svgr/webpack'],
      },
    ],
  },
  //...
};

Now you can import SVG images as React components and use them in our code like so:

import React from 'react';
import ReactLogo from './logo.svg';

const App = () => {
  return (
    <div className="App">
      <ReactLogo />
    </div>
  );
}
export default App;

Using SVG as a Data URL

Data URLs are URLs prefixed with the data: scheme, which allows content creators to embed small files inline in documents. You can read more about them here. This approach allows us to use SVG images like an inline element.

So how do you achieve this? First, you’ll need an appropriate webpack loader in your bundler. For this use case, I’ll use svg-url-loader. You can grab it into your project by running this command> $ npm install svg-url-loader --save-dev.

Then, update the webpack configuration file rules section with the following:

const webpack = require('webpack');

module.exports = {
  entry: './src/index.js',
  module: {
    rules: [
      //...
      {
        test: /\.svg$/,
        use: [
          {
            loader: 'svg-url-loader',
            options: {
              limit: 10000,
            },
          },
        ],
      },
    ],
  },
  //...
};

Now you can import your SVG file and use it in your React component like this:

import ReactLogo from './logo.svg';

const App = () => {
  return (
    <div className="App">
      <img src={ReactLogo} alt="React Logo" />
    </div>
  );
}

<img src="ebbc8779488b4073081931bd519478e8.svg" alt="" />

This usually compiles into something like this in the DOM:

<img src="a34r2dad4234dad7824sa4284r0s2345.svg" alt="React Logo" />

See how SVGs impact your users with LogRocket

SVGs help with performance and add a great level of animation, interactivity, and more, but sometimes they have unintended consequences for end users. If you’re interested in monitoring how your SVGs render in your React apps, tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — .

Things to note

  • Complicated images: The more complex the image, the larger the SVG file gets; we saw this while trying to use the <svg> element. Here, I would recommend you go with PNG or JPEG
  • Backwards support on the web: SVG doesn’t have backwards browser support, which means most older browser versions won’t support SVG. As such, SVG might not display correctly for users who are still on those versions. If you are targeting older versions of browsers, SVG might not be your go-to image format

Conclusion

SVGs are really useful for building fast, performant, and accessible webpages. Knowing when and when not to use them will serve you even better. I recommend you use SVGs for low-intensity images like logos, icons, and less-complex images.



Nedy Udombat Software engineer.

11 Replies to “How to use SVGs in React”

  1. Looks like a lot of editing of Webpack. What’s the best way to use SVG’s without ejecting?

  2. I tried this, but the SVG doesn’t show when using an image tag. I don’t know what I am missing. I installed file-loader, too.

  3. Great article! One usage not mentioned above, using as inline background image:
    .elem {
    background-image: url(‘data:image/svg+xml, ……’);
    }

  4. I second, this is a great article!
    Would also like to add the the object tag can be used (…)

    But, more important – this article does not relate the fact that some of the methods listed here inline the SVG into the DOM – which allows developers to use CSS and JS to manipulate the SVG which is amazing !

  5. You can use something like react-app-rewired to provide access to a webpack config file without ejecting.

  6. “export ‘ReactComponent’ (imported as ‘ReactLogo’) was not found in ‘../static/images/icon/svg/feather–white.svg’
    i go this error messages after using ReactComponent step, what should i do?

  7. If you’re using CRA just import it as a component like in the example. All the SVGR business is handled for you already

  8. “Then we update our Webpack configuration rule to use SVGR for SVGs”. What file is that? With witch name I need to create it?

  9. “ With this, we can already see the disadvantage of using this method, when the image is more complex the SVG file becomes larger and since SVG is stored in text, that means we have a whole bunch of text in our code.”

    What are the disadvantages? Is it solely the amount of text in the code? Or is there another disadvantage?

  10. Thanks for sharing mate! Using SVG as a component worked like dream for me. One cool thing is that it creates an inline SVG which to which we can pass props such as className and control its presentation that way.

Leave a Reply