loading...

Using a string of SVG text as an image source

benjaminblack profile image Benjamin Black Updated on ・2 min read

My posts are usually notes and reference materials for myself, which I publish here with the hope that others might find them useful.

TL;DR:

let svg = `<svg xmlns="http://www.w3.org/2000/svg" ...`;
let blob = new Blob([svg], {type: 'image/svg+xml'});
let url = URL.createObjectURL(blob);
let image = document.createElement('img');
image.src = url;
image.addEventListener('load', () => URL.revokeObjectURL(url), {once: true});

It is sometimes useful to compose an SVG programmatically as a string. Using that string as the src of an image is fairly straightforward (with one "gotcha".)

Step one: you need a string of SVG text.

let svg = `<svg ...`;

Step two: convert the string to a blob.

let blob = new Blob([svg], {type: 'image/svg+xml'});

Step three: create a URL to the blob.

let url = URL.createObjectURL(blob);

Step four: create an image referencing the URL.

let image = document.createElement('img');
image.src = url;

Step five: revoke the URL once the image loads for cleanup.

image.addEventListener('load', () => URL.revokeObjectURL(url), {once: true});

However, the following does not work:

let svg = `
<svg width="50" height="50">
    <circle cx="25" cy="25" r="20"/>
</svg>`;

This results in a broken image:

broken image

The xmlns attribute must be included on the <svg> element:

let svg = `
<svg width="50" height="50" xmlns="http://www.w3.org/2000/svg">
   <circle cx="25" cy="25" r="20"/>
</svg>`;

And now it works:

working image

Chrome is not tolerant of a missing xmlns attribute in this case, which is, I guess, consistent: only inline <svg>s, embedded inside HTML markup, are allowed to omit the xmlns attribute. External SVGs, used as the src of an <img>, must include it, apparently even if the SVG is "inline" in the sense that it created by the document itself as a blob, and even if the MIME type is image/svg+xml.

Posted on Sep 13 '18 by:

benjaminblack profile

Benjamin Black

@benjaminblack

Web developer / byproduct of stellar nucleosynthesis

Discussion

markdown guide
 

Second option would be data:image/svg+xml, and encodeURIComponent. See codepen.io/tigt/post/optimizing-sv...

 

Blob is not defined in Node.js file?? Any Suggestions?