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?
<use xlinkHref="/svg/svg-sprite#my-icon" />
.
xlink:href
is deprecated, now supposed to just use href
-- developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
xlink:href
so we still need to use it. Actual web applications need to either use the common denominator of browser features, or implement specific workarounds / polyfills.
Property 'xlink' does not exist on type 'SVGProps<SVGImageElement>
MDN says that xlink:href
is deprecated in favor of href
. You should be able to use the href
attribute directly. The example below includes both versions.
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 2018-06-09: Added info about href
vs xlink:href
attributes and updated example to include both. Thanks @devuxer
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 = ( ); 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, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); }
<svg viewBox="0 0 1340 667" width="100" height="100" > <image width="667" height="667" href="https://i.imgur.com/w7GCRPb.png"/> { /* Deprecated xlink:href usage */ } <image width="667" height="667" x="673" xlinkHref="https://i.imgur.com/w7GCRPb.png"/> </svg>
ReactDOMServer.renderToStaticMarkup()
output:ReactDOM.render()
output:
Update september 2018: this solution is deprecated, read Jon’s answer instead.
--
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 }} />;
}
dangerouslySetInnerHTML
. You can use xlinkHref
as mentioned below.
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
).
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' }, '' )
)
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>
I had problems with showing SVG in Gutenberg block, by referencing it with xlink:href
. We used xlinkHref
property in react, but after compiling, instead to render as xlink:href
it was rendered to xlinkhref
, and SVG was not displayed. After a lot of examining, I found out that xlink:href
is deprecated (although it worked if we add it in html, or directly in chrome dev tools), and that href
should be used instead. So after changing it to href
it worked.
"SVG 2 removed the need for the xlink namespace, so instead of xlink:href you should use href." https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
This is the code I used
SVG file
<svg id="svg-source" style="display: none;" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
<symbol id="svg-arrow-accordion" viewBox="0 0 15 24" fill="none">
<path id="Path_1662" data-name="Path 1662" d="M15.642,14.142h-3V1.5H0v-3H15.642Z" transform="translate(2 2) rotate(45)" fill="currentColor"></path>
</symbol>
</svg>
React file
<svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" width="15" height="24">
<use href="#svg-arrow-accordion"></use>
</svg>
Success story sharing
xlink:href
has been deprecated, and the recommendation is to usehref
without the namespace prefix. (Note, however, if you're using TypeScript, the typings haven't yet been updated to reflect this.)