5

I am using React, and I am trying to load a svg icon from a sprite. My sprite is like this:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <symbol viewBox="0 0 28.3 28.3" id="square">
      <path d="M.3 30.7h27L13.8 3.8zM126.3-51.7c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16z" />
      <path d="M0 28.3h28.3L14.2 0 0 28.3zm5.3-3.2l8.9-17.7L23 25.1H5.3z" />
    </symbol>
    <symbol viewBox="0 0 28.3 28.3" id="circle">
      <circle cx="14.2" cy="14.2" r="14.2" />
    </symbol>
  </defs>
</svg>

And I load it with:

<svg viewBox="0 0 28.3 28.3" className="App-icon">
    <use xlinkHref="./sprite#square" />
</svg>

With no results. I made a sandbox as an example: https://codesandbox.io/s/l711v6j7v7

  • Have you tried exporting the sprites as individual react components, importing them and rendering them as you would any other react component? – Drew Reese Nov 26 '18 at 16:30

2 Answers2

4

If you want to reference it as external resource you need to use the proper URL to the svg file and it needs to be publicly accessible. So in the codesandbox you need to move it to the public folder, so that you can access it in the browser via

https://codesandbox.io/s/l711v6j7v7/sprite.svg

Then you can reference it like this:

<use href="/sprite.svg#square" />

See this fork of your codesandbox.

Aamnah
  • 559
  • 6
  • 9
Stefan
  • 675
  • 3
  • 9
  • Yes, it works; but what if I have my sprite in a separate file, as in the sandbox? –  Nov 26 '18 at 16:33
  • You can put it in a separate component, but you have to render the component. See this modification of your sandbox: https://codesandbox.io/s/0p5owx8ozn – Stefan Nov 26 '18 at 16:34
  • I see… The problem is that my sprite is created by [svg-sprite-loader](https://github.com/kisenka/svg-sprite-loader), and I have to call it as it is. Is there any way I can render it from the file? –  Nov 26 '18 at 16:37
  • Ah ok, I've modified the sandbox. You need to move the sprite.svg into the public folder and make sure to reference it like this: `xlinkHref="/sprite.svg#circle"` – Stefan Nov 26 '18 at 16:53
  • Hm, looks good, but… what if my public folder is `dist`, and the sprite is inside `dist/svg/sprite.svg`? –  Nov 26 '18 at 17:03
  • You can use any folder structure as long as in the end the file is accessible directly via the browser. So I would recommend to put it where your other static assets (i.e. pictures, font files, etc.) are. It's hard to answer definitively without knowing your setup though. I think if I understand correctly it should be for example `/dist/svg/sprite.svg#circle` then. – Stefan Nov 26 '18 at 17:06
  • Yeah, I got it! :) –  Nov 26 '18 at 17:12
  • `xlink:href` is [deprecated](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href) since SVG 2, you should use `href` instead. – Aamnah Aug 31 '21 at 18:06
2

For those where the SVG file is an existing/external svg file. You probably have an existing SVG webpack loader which is not working with the concept of SVG sprites. Why? It generally needs a file reference/url to the sprite file or the SVG (nodes) must exist in the DOM (Solution below)

This works:

  1. Transform the plain SVG to JSX (google html to jsx)
  2. Create a new pure react component and simply return the transformed JSX in render() method
  3. Import and include the created react sprite component
  4. Now use the sprite symbol via <use><svg href="#symbolnameorid"></svg></use> You can use it without the file prefix now
Marc
  • 2,659
  • 3
  • 34
  • 41