New Feb 24, 2026

Can't get svg markup to render as a data uri in an image source [duplicate]

Libraries, Frameworks, etc. All from Newest questions tagged vue.js - Stack Overflow View Can't get svg markup to render as a data uri in an image source [duplicate] on stackoverflow.com

I am attempting to get the google material symbols loaded into a canvas to download them. This is generally straight forward, except the fill property in the font-variation-settings. This I cannot get to work in the canvas. I only saw how to kind of do this through this SO post, but this is not working for me.

My attempt:

const canvas = document.createElement( "canvas" );

const svgNS = 'https://www.w3.org/2000/svg'; const svg = document.createElementNS( svgNS, "svg" );

const style = document.createElementNS( svgNS, "style" ); style.textContent = @font-face { font-family: 'Material Symbols Outlined'; font-style: normal; font-weight: 100 700; src: url('https://fonts.gstatic.com/s/materialsymbolsoutlined/v315/kJEhBvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oFsI.woff2') format('woff2'); } .material-symbols-outlined { font-family: 'Material Symbols Outlined'; font-weight: normal; font-style: normal; font-size: 24px; /* Preferred icon size */ display: inline-block; line-height: 1; text-transform: none; letter-spacing: normal; word-wrap: normal; white-space: nowrap; direction: ltr; }; svg.append( style );

const foreignObject = document.createElementNS( svgNS, "foreignObject" ); foreignObject.setAttribute( "x", '0' ); foreignObject.setAttribute( "y", '0' );

const clone = icon.cloneNode(true); foreignObject.append( clone );

const { width, height } = icon.getBoundingClientRect(); foreignObject.setAttribute( "width", ${width} ); foreignObject.setAttribute( "height", ${height} ); svg.setAttribute( "width", ${width} ); svg.setAttribute( "height", ${height} );

svg.append( foreignObject );

const svg_markup = new XMLSerializer().serializeToString( svg ); const svg_file = new Blob( [ svg_markup ], { type: "image/svg+xml" } );

Object.assign( canvas, { width, height } ); const ctx = canvas.getContext( "2d" );

const img = new Image(); img.onload = () => { console.log('img loaded'); }; img.onerror = () => { console.log('image failed to load'); } const svgURL = 'data:image/svg+xml,' + encodeURIComponent(svg_markup); img.src = svgURL;

No matter what, the img onerror always fires. I can go to the data uri I get and it is valid. the I have even tried turning the turning svg_file blob into a data uri and using that. Same issue, I can go to that data uri, but img always throws an error. I don't get it!

And of course the onerror for img doesn't give any info on why it failed. There are no errors in the console. It just hits the onerror.

I tried to simplify it too by just putting the svg markup as the canvas innerHTML, of course that didn't work...

Wondering if anyone has any clue how I may get the google material symbols to be able to apply the FILL font-variation-setting to render in canvas to download. Just toggling it on the span or parent container doesn't work. Canvas doesn't naturally pick that css attribute up it seems.

Scroll to top