Using svg files in React

Hi!

Does anyone know how to use an svg file in React? I am using Webpack and trying to use an svg file that I have saved. I have currently tried the following solutions, to no avail:

import React, { Component } from 'react'

import mySvg from './logo.svg'

class Header extends Component {

  render() {
    return (
        <div className='header'>
            <img src={mySvg} />
        </div>
    );
  }
};

export default Header

as well as

import Logo from './logo.svg';

class App extends Component {
  render() {
    return (
      <div className="App">
          <Logo fill="red" className="logo" width={50} height={50} />
      </div>
    );
  }
}
and minimum config looks like this:

{
  test: /\.svg$/,
  use: [
    {
      loader: "babel-loader"
    },
    {
      loader: "react-svg-loader",
      options: {
        jsx: true // true outputs JSX tags
      }
    }
  ]
}

I’m so confused as to why this is so difficult? I must be missing something obvious?

Thanks!

1 Like

Edited: I’ve never used that plugin so what I had said makes no sense, sorry.

Yeah, I just read that lol

I appreciate the help, but I couldn’t get that to work either. I’m sure I must be missing something obvious, but I can’t figure it out.

Is SVG not supposed to be used with React? I would never have imagined it would be this hard to figure out.

Hi @jv88899,

I think for your use-case, an inline SVG is appropriate (which is totally doable in React). Here’s a code snippet:

import React from 'react';

export const Logo = (props) => {
  const { url, reversed, shrunk } = props;
  return (
    <a className={`logo ${reversed ? 'reversed' : ''} ${shrunk ? 'shrunk' : ''}`} href='/'>
      <svg viewBox="0 0 227 49" xmlns="http://www.w3.org/2000/svg">
        <defs>
          // SVG code here
        </defs>
        <g className="triangles">
          <path className="big-triangle" d="M.067 48.217L15.543 20.27a.522.522 0 0 1 .914 0l15.476 27.948a.526.526 0 0 1-.457.783H.524c-.4 0-.651-.432-.457-.783" />
          <g transform="translate(17)" className="little-triangle">
            <mask id="b">
              <use xlinkHref="#a" />
            </mask>
            <path d="M16.584 1.451l-7.518 13.47a.517.517 0 0 1-.904 0L.644 1.451a.517.517 0 0 1 .451-.77h15.036c.397 0 .646.425.453.77" mask="url(#b)" />
          </g>
        </g>
        <g className="text">
          // SVG code here
        </g>
      </svg>
    </a>
  );
};

And your corresponding css might look like this:

/*=============================================>>>>>
= Logo Component Styles =
===============================================>>>>>*/
.logo {
  display: block;
  width: 150px;
  height: 35px;

  svg {
    transition: fill 0.3s ease;
    .text {
      fill: $primary;
      opacity: 1;
      transition: opacity 0.3s ease;
    }
    .triangles {
      .little-triangle {
        fill: $secondary;
      }
      .big-triangle {
        fill: $primary;
      }
    }
  }

  &.reversed {
    svg {
      .text {
        fill: $white;
      }
      .triangles {
        .little-triangle {
          fill: $secondary;
        }
        .big-triangle {
          fill: $white;
        }
      }
    }
  }
  &.shrunk {
    
  }
}

An awesome tool for getting & cleaning up SVG markup can be found here: https://jakearchibald.github.io/svgomg/

Hope this helps!

I think I need to give it a try to that plugin. I USED SVG quite often with React but I always made my own components that render the SVG code as I need it. I suppose this plugin makes it better.

Try To make SVG code as component and render that component where You want to use

Yes, I’m with @Parmar93 on this. I think that’s the most straightforward approach, but as I said I never tried one of those webpack plugins, so maybe it’s not the best way to do it.

@jv88899 Have a look at my Pomodoro. I used SVG from line 514 onwards. Maybe it can be useful for you.

I’ve used https://github.com/gilbarbara/react-inlinesvg in the past and it worked well. The images were hosted elsewhere though, so I just passed in the path. Worked pretty easily out of the box. The advantage of this library is you can style the fill and target elements within the svg with css.

You could also try <img src={path} /> and host the svg on github.

Do you have a github repo or have this in an online editor so people here can have a look and help you out?

I would think the best way is using object tag
<object src…

I recently wrote an article offering a solution for inlining SVGs in React app.

What I did was I turned the SVG into a component and then just brought it into my application that way so:

const Logo = () => {
  return (
    <svg>
        <path x= xxxxxxxxxx>
   </svg>
  )
}

then in my main file:

import Logo from '../../../images/logo.js'

then inside my component(where I want to use the svg):

<div>
<Logo/>
</div>

You could keep the component in the same file or put it into a different file, thats up to you, depends on the situation.

Know I am a bit late to this conversation, but check out this page. It shows how to turn your SVG directly into a React Component. https://css-tricks.com/creating-svg-icon-system-react/