Embedding SVG into ReactJS

151,220

Solution 1

Update 2016-05-27

As of React v15, support for SVG in React is (close to?) 100% parity with current browser support for SVG (source). You just need to apply some syntax transformations to make it JSX compatible, like you already have to do for HTML (classclassName, style="color: purple"style={{color: 'purple'}}). For any namespaced (colon-separated) attribute, e.g. xlink:href, remove the : and capitalize the second part of the attribute, e.g. xlinkHref. Here’s an example of an svg with <defs>, <use>, and inline styles:

function SvgWithXlink (props) {
    return (
        <svg
            width="100%"
            height="100%"
            xmlns="http://www.w3.org/2000/svg"
            xmlnsXlink="http://www.w3.org/1999/xlink"
        >
            <style>
                { `.classA { fill:${props.fill} }` }
            </style>
            <defs>
                <g id="Port">
                    <circle style={{fill:'inherit'}} r="10"/>
                </g>
            </defs>

            <text y="15">black</text>
            <use x="70" y="10" xlinkHref="#Port" />
            <text y="35">{ props.fill }</text>
            <use x="70" y="30" xlinkHref="#Port" className="classA"/>
            <text y="55">blue</text>
            <use x="0" y="50" xlinkHref="#Port" style={{fill:'blue'}}/>
        </svg>
    );
}

Working codepen demo

For more details on specific support, check the docs’ list of supported SVG attributes. And here’s the (now closed) GitHub issue that tracked support for namespaced SVG attributes.


Previous answer

You can do a simple SVG embed without having to use dangerouslySetInnerHTML by just stripping the namespace attributes. For example, this works:

        render: function() {
            return (
                <svg viewBox="0 0 120 120">
                    <circle cx="60" cy="60" r="50"/>
                </svg>
            );
        }

At which point you can think about adding props like fill, or whatever else might be useful to configure.

Solution 2

If you just have a static svg string you want to include, you can use dangerouslySetInnerHTML:

render: function() {
    return <span dangerouslySetInnerHTML={{__html: "<svg>...</svg>"}} />;
}

and React will include the markup directly without processing it at all.

Solution 3

According to a react developer, you dont need the namespace xmlns. If you need the attribute xlink:href you can use xlinkHref from react 0.14

Example

Icon = (props) => {
  return <svg className="icon">
    <use xlinkHref={ '#' + props.name }></use>
  </svg>;
}

Solution 4

If you want to load it from a file, you may try to use React-inlinesvg - that's pretty simple and straight-forward.

import SVG from 'react-inlinesvg';

<SVG
  src="/path/to/myfile.svg"
  preloader={<Loader />}
  onLoad={(src) => {
    myOnLoadHandler(src);
  }}
>
  Here's some optional content for browsers that don't support XHR or inline
  SVGs. You can use other React components here too. Here, I'll show you.
  <img src="/path/to/myfile.png" />
</SVG>

Solution 5

You can import svg and it use it like a image

import chatSVG from '../assets/images/undraw_typing_jie3.svg'

And ise it in img tag

<img src={chatSVG} className='iconChat' alt="Icon chat"/>
Share:
151,220
nicholas
Author by

nicholas

Updated on July 08, 2022

Comments

  • nicholas
    nicholas almost 2 years

    Is is possible to embed SVG markup into a ReactJS component?

    render: function() {
      return (
        <span>
          <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmln ...
        </span>
      );
    }
    

    Results in the error:

    Namespace attributes are not supported. ReactJSX is not XML.

    What is the lightest way of doing this. Using something like React ART is way overkill for what I'm trying to do.

  • Andy
    Andy almost 9 years
    I'm controlling some paths inside SVG using React, but React doesn't seem to support the filter elements. Is there a way to support this? Seems like dangerouslySetInnerHTML won't work because I can't put a span inside an SVG and I can't use that to set the filter attribute on the paths. I don't suppose there's a way to create React elements as usual but have them pass all attributes verbatim to the DOM elements?
  • Andrew Patton
    Andrew Patton almost 7 years
    @ChinonsoChukwuogor Great question! I don’t know, I’ve never used React Native. Did you give it a go?
  • HelloWorld
    HelloWorld almost 6 years
    @AndrewPatton Multiple Css Class names with the tick char does not work: '.class1, .class2{fill: #005baa;}' How can I fix that?
  • Andrew Patton
    Andrew Patton almost 6 years
    @HelloWorld Can you give me an example where it doesn’t work? I just forked my original demo to add classB and it worked: codepen.io/acusti/pen/BVJzNg
  • Shnd
    Shnd almost 5 years
    As 2019, seems that you can use dangerouslySetInnerHTML but still I couldn't make shadow filter to work on Chrome using dangerouslySetInnerHTML, but it's working on Firefox.
  • funder7
    funder7 almost 4 years
    Thanks, starting from this I've managed to import an svg from file as a React component without any loader, I've just removed ``` xmlns:osb="openswatchbook.org/uri/2009/osb"``` from the svg tag, leaving only the xlmns. It's all about tag parsing apparently. Just in case, I've followed these steps as well: blog.logrocket.com/how-to-use-svgs-in-react
  • jordanfb
    jordanfb over 3 years
    Why do people tolerate JSX?
  • Phani Rithvij
    Phani Rithvij over 3 years
    The question asks for embedding svg inline specifically.
  • Muhammed Moussa
    Muhammed Moussa almost 3 years
    so what if you need to change the color?
  • leopinzon
    leopinzon over 2 years
    I believe this isn't what's originally asked