Nedy Udombat Software Engineer

How to use SVGs in React

5 min read 1625

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, etc., use SVG for some of their images and icons.

Why SVG over other image formats?

There are other image formats that we are more familiar with such as JPEGs, GIFs, PNGs, etc. We will take a look at some advantages of using SVG over other image formats.

  • Scalability and resolution: This is the utmost advantage of SVG over others, 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 any quality and gives SVG the ability to scale infinitely
  • Minimal file size: The file sizes of SVG images are usually small compared to other file formats and they are easily compressible, giving it a possibility to be even smaller
  • High performance and speed: Because of the small size nature of SVG images, it becomes very easy and fast for browsers to render them. It is 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 every 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 Monalisa photo, I would suggest using, PNGs or JPEGs as the load time and performance for SVGs fall drastically
  • DOM-like and style-able: SVG images are like code, so this means it can be navigated like a DOM element and also styled, although some properties have different names eg(you might want to use fill instead of color). It can also be styled with CSS
  • Editable: Since SVGs are DOM-like, SVG’s can be created and edited and animated with any text editor
  • Integration: SVGs can be used in various ways, it can be used to display logo images and icons. It can be used as graphs, animations, and effects
  • Animatable: SVGs can be animated. This can be done with tools like Web Animation API’s, WebGL, CSS animations, etc. For animating SVG with CSS, check out this detailed article by Hope Armstrong
  • Accessibility and SEO: SVGs contain text which improves the accessibility of a website and it also means they can be searched, indexed, scripted, etc.

How to use SVGs in React

svg react example

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

Using image tag for static SVGs

In order to be able to use SVGs or any other image format in the img <img src={} /> we have to set up a file loader system in whichever module bundler we are using(Webpack, Parcel, etc). Here I will show you how to set it up in a few steps if you are already using Webpack.

First, we install the file-loader library $ npm install file-loader --save-dev, this will install it as a dev-dependency.

And 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 tag

With the same Webpack settings above we can use the SVG tag, basically copying and pasting the content of the .svg file into your 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;

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.

We made a custom demo for .
No really. Click here to check it out.

Using 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, instead, it’s rendered along 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 this approach only works with create-react-app, If you are not using create-react-app, I would recommend using other approaches. Create-react-app uses SVGR under the hood to make it possible to transform and import SVG as a React component.

Using SVGR

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

First, we install the package $ npm install @svgr/webpack --save-dev.

Then we update our 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 we can import our SVG images as a React component and use it in our code like this:

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 that allow content creators to embed small files inline in documents, you can read more about it here. This approach allows us to use SVG images like an inline element.

So how do we achieve this? First, we need an appropriate Webpack loader in our bundler, in the use case, I will be using svg-url-loader. We can grab it into our project by running this command $ npm install svg-url-loader --save-dev.Then we will update the Webpack configuration file rules section with these rules:

const webpack = require('webpack');

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

Now we can import our SVG file and use it in our 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 complies into something like this in the DOM

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

Things to note

  • Complicated images: The more complex the image the larger the SVG file gets like we saw while trying to use the SVG tag. Here I will recommend you go with PNG or JPEG
  • Backwards support on the web: SVG doesn’t have backwards browser support, which means that not all older versions of browsers support SVG, so SVG might not display correctly in those browsers. This is due to the fact that initially when SVG was first introduced most browsers did not support SVG. 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.

Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and 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 with 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 — .

Nedy Udombat Software Engineer

One Reply 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?

Leave a Reply