0

We have hundreds of SVG files that I am trying to render inline. I am using create-react-app which already has @svgr/webpack installed and configured. It allows me to add SVG inline like so:

import { ReactComponent as SvgImage } from '../Plans/Brownlow-Floor-Plan.svg';
...

<SvgImage style={{ width: "600px !important" }} />

enter image description here

Similar question provides a solution for dynamically rendering SVG inline. However, In my case, I don't have any SVG files in the source code. Instead, all SVG files are returned to me via a call to an API service. For example:

  • http://myservice/api/getplan(100)
  • http://myservice/api/getplan(103)
  • http://myservice/api/getplan(106)
  • http://myservice/api/getplan(631)

As a result, by the time webpack is run, it has no information about these SVG files.

So my question is: is it possible to render svg dynamically in react (TypeScript) if I pull SVG file from an external URL?

This is not a duplicate question: How to dynamically import SVG and render it inline

Approach described in the question above is not going to work because it expects all SVG files to be added to the source code.

This approach also not going to work because simply using an img tag will not pull SVG inline:

<img src="plan.svg" />

enter image description here

Including SVG via an img tag make these kinds of things impossible: enter image description here

Any help will be greatly appreciated!

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Denis Molodtsov
  • 802
  • 12
  • 27
  • is this your answer ? https://stackoverflow.com/q/61339259/12232340 –  Oct 22 '21 at 22:54
  • @Dlk, thank you, but I specifically mentioned this post in my question and explained that it's no the same question. The solution provided in that post does not apply to my case. I explain the reasons in my question above. – Denis Molodtsov Oct 22 '21 at 22:58

2 Answers2

3

There's an excellent package called react-svg that does exactly what you want.

You can use it with a simple src property that takes a url string, just like an <img> tag. But behind the scenes, it will download the svg file from the url and inject it inline. For example:

import { ReactSVG } from 'react-svg'

Component = () => <ReactSVG src="http://somewhere.com/my.svg" />,
Andrew Stegmaier
  • 3,429
  • 2
  • 14
  • 26
  • thank you very much! this is an amazing component. Exactly what I was looking for. I was already considering using using dangerouslySetInnerHTML to to set SVG this way, but ReactSVG is much better! – Denis Molodtsov Oct 23 '21 at 01:56
0

I am not sure if this will work for you but, you can try to using the tag <use /> within an <svg /> tag. For example:

<svg
    height={iconHeight}
    viewBox={`0 0 ${iconWidth} ${iconHeight}`}
    width={iconWidth}
>
    <use xlinkHref={`${svgPath}#${icon}`} />
</svg>

Where svgPath is the URL to the SVG, and icon is an ID set on the SVG. You can try to omit to the #${icon} portion.

Not sure if this helps though.

If you choose this route, you may be incompatible with IE... For that you can use svg4everybody, but tbh IE is dead and it should stay dead.

Cheers!

segFault
  • 3,887
  • 1
  • 19
  • 31