Home » Reactjs » SVG use tag and ReactJS

SVG use tag and ReactJS

Posted by: admin November 30, 2017 Leave a comment

Questions:

So normally to include most of my SVG icons that require simple styling, I do:

<svg>
    <use xlink:href="/svg/svg-sprite#my-icon" />
</svg>

Now I have been playing with ReactJS as of late evaluating it as a possible component in my new front-end development stack however I noticed that in its list of supported tags/attributes, neither use or xlink:href are supported.

Is it possible to use svg sprites and load them in this way in ReactJS?

Answers:

React doesn’t support all SVG tags as you say, there is a list of supported tags here. They are working on wider support, f.ex in this ticket.

A common workaround is to inject HTML instead for non-supported tags, f.ex:

render: function() {
    var useTag = '<use xlink:href="/svg/svg-sprite#my-icon" />';
    return <svg dangerouslySetInnerHTML={{__html: useTag }} />;
}

Questions:
Answers:

As of React 0.14, xlink:href is available via React as the property xlinkHref. It is mentioned as one of the “notable enhancements” in the release notes for 0.14.

<!-- REACT JSX: -->
<svg>
  <use xlinkHref='/svg/svg-sprite#my-icon' />
</svg>

<!-- RENDERS AS: -->
<svg>
  <use xlink:href="/svg/svg-sprite#my-icon"></use>
</svg>

Update 3: At time of writing, React master SVG properties can be found here.

Update 2: It appears that all svg attributes should now be available via react (see merged svg attribute PR).

Update 1: You may want to keep an eye on the svg related issue on GitHub for additional SVG support landing. There are developments in the works.

Demo:

const svgReactElement = (
  <svg
    viewBox="0 0 667 667"
    width="100"
    height="100"
  >
    <image width="667" height="667" xlinkHref="https://i.imgur.com/w7GCRPb.png"/>
  </svg>
)

var resultHtml = ReactDOMServer.renderToStaticMarkup(svgReactElement)
document.getElementById('render-result-html').innerHTML = escapeHtml(resultHtml)

ReactDOM.render(svgReactElement, document.getElementById('render-result') )

function escapeHtml(unsafe) { return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "'"); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom-server.browser.development.js"></script>

<h2>Render result of rendering:</h2>
<pre>&lt;svg
  viewBox="0 0 667 667"
  width="100"
  height="100"
&gt;
  &lt;image width="667" height="667" xlinkHref=&quot;https://i.imgur.com/w7GCRPb.png&quot; /&gt;
&lt;/svg&gt;</pre>

<h2><code>ReactDOMServer.renderToStaticMarkup()</code> output:</h2>
<pre id="render-result-html"></pre>
<h2><code>ReactDOM.render()</code> output:</h2>
<div id="render-result"></div>

Questions:
Answers:

As already said in Jon Surrell’s answer, use-tags are supported now. If you are not using JSX, you can implement it like this:

React.DOM.svg( { className: 'my-svg' },
    React.createElement( 'use', { xlinkHref: '/svg/svg-sprite#my-icon' }, '' )
)

Questions:
Answers:

If you encounter xlink:href, then you can get the equivalent in ReactJS by removing the colon and camelcasing the added text: xlinkHref.

You’ll probably eventually be using other namespace-tags in SVG, like xml:space, etc.. The same rule applies to them (i.e., xml:space becomes xmlSpace).

Questions:
Answers:

I created a little helper that works around this issue: https://www.npmjs.com/package/react-svg-use

first npm i react-svg-use -S then simply

import Icon from 'react-svg-use'

React.createClass({
  render() {
    return (
      <Icon id='car' color='#D71421' />
    )
  }
})

and this will then generate the following markup

<svg>
  <use xlink:href="#car" style="fill:#D71421;"></use>
</svg>