<use> tag to load svg from external url

Viewed 65

I want to load svg from external URL by using <use> tag so that I can have some more control on my svg instead of <img> tag. But when I am using svg on the same page and loading using <use> tag it is working perfect. But as I am uploading svg to external URL and putting URL in <use> then it is not working.

Working example code

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display: none;">
<defs>
<g id="icon-image">
  <path class="path1" d="M0 4v26h32v-26h-32zM30 28h-28v-22h28v22zM22 11c0-1.657 1.343-3 3-3s3 1.343 3 3c0 1.657-1.343 3-3 3-1.657 0-3-1.343-3-3zM28 26h-24l6-16 8 10 4-3z"></path>
</defs>
</svg>

<h1>
  Photo Gallery
  <svg viewBox="0 0 32 32">
    <use fill="blue" xlink:href="#icon-image"></use>
  </svg>
</h1>

But I want something like this (Not Working). I have upload the same svg image on external URL but it is not showing up on the page.

<h1>
  Photo Gallery
  <svg viewBox="0 0 32 32">
    <use fill="blue" xlink:href="https://cdn.jsdelivr.net/gh/instanano/apparatus/test555.svg#icon-image"></use>
  </svg>
</h1>

1 Answers

As @Robert Longson already has pointed out:
You might not be able to embed external svg symbol/defs references due to security settings.

Provided the external host permits cross origin access for svg files, you can use these polyfills:

CDNs dedicated to script libraries like jsdelivr will usually add suitable CORS headers (or provide some options to allow cross origin access).

On the other hand: svg sharing sites like svgshare don't allow remote access (but it works fine for <img> elements, but you won't be able to fetch and parse the svg DOM).

Example 1: using @thasmo's external-svg-polyfill

For some reasons this polyfill doesn't work in SO snippets on iOs safari

window.document.addEventListener('DOMContentLoaded', function() {
  new ExternalSvgPolyfill();
});
svg {
  display: inline-block;
  width: 25%;
  border: 1px solid #ccc
}
<!--  works! -->
<svg viewBox="0 0 32 32">
    <use fill="blue" xlink:href="https://cdn.jsdelivr.net/gh/instanano/apparatus/test555.svg#icon-image" />
  </svg>

<!--won't work -->
<svg viewBox="0 0 32 32">
    <use fill="blue" xlink:href="https://svgshare.com/i/mJH.svg#icon-image" />
</svg>

<script src="https://cdn.jsdelivr.net/npm/@thasmo/external-svg-polyfill@2/browser/bundle.min.js"></script>

Example 2: using svgxuse by @Keyamoon

svg{
  display:inline-block;
  width:25%;
  border: 1px solid #ccc
}
<svg viewBox="0 0 32 32">
    <use fill="blue" href="https://cdn.jsdelivr.net/gh/instanano/apparatus/test555.svg#icon-image" />
  </svg>
<svg viewBox="0 0 32 32">
    <use fill="blue" xlink:href="https://svgshare.com/i/mJH.svg#icon-image" />
  </svg>

<script src="https://cdnjs.cloudflare.com/ajax/libs/svgxuse/1.2.6/svgxuse.min.js"></script>

Both polyfills fetch the external svg contents and append it as a hidden inlined <svg> element to the DOM.

See also: (Understanding CORS and SVG)

Related