Load SVG dynamically from CMS

Hi folks,

I’m trying to build this dynamic header and I wanted to also load the SVG dynamically too.

So I created a regular text field on my Collection (Categorias), then I populated the field (I called it ‘svgcode’) of the item I’m trying to load

And then on the designer I’m trying to recall that code into an html embed which is how I usually load regular SVGs. I apparently connected right the html embed to the field of the CMS which has the code

but it doesn’t work. It displays the code loaded from the CMS as plain text as you can see.

What am I missing? Any help would be much appreciated.

Here is my public share link: LINK
(how to access public share link)

You can load SVGs directly into a CMS Image field. When that meets your needs, it’s usually the preferred approach because it’s easier to manage, displays in the designer, and allows 4mb files instead of only 10k chars.

However there are situations where you need the SVG to be inline, e.g. when you want to make use of the currentColor feature.

In the CMS, the text field is designed for text only, so Webflow always HTML encodes the contents whenever it is referenced in your page - even when it’s referenced within an HTML Embed. Unfortunately the CMS does not yet have a raw HTML Embed field type, however you can hack this by using the one that is built into the Rich Text element.

  • Add a rich text field to the CMS
  • In side the rich text content for an item, add an HTML Embed.
  • Paste your code
  • Bind your rich text field to a rich text element on your page, and you’ll get your code ( wrapped in a couple of divs ).

Not ideal, but it works.

Another way is to store your content as plaintext, and then HTML decode it using script.
Here you’ll get a slight delay before the decode happens.

This is a funky approach I’ve used before, which is a self-replacing script. Place your HTML Embed where you want the decoded content to go. Drop this script in and put your embedded field that allows you to easily position the decoded content.

When the document renderer hits the script, it will process it, decode your HTML, and then replace the script element with the newly decoded element.

Restrictions- in this approach, your encoded content cannot contains any backticks (`), because it will likely break the script.

(function() { // IIFE

    // Replace this string with the CMS field you are decoding
    var htmlString = `YOUR CMS FIELD EMBED HERE`;

    // Prepare your decoded content
    function decodeHtml(html) {
        var doc = new DOMParser().parseFromString(html, "text/html");
        return doc.documentElement.textContent;
    var decodedString = decodeHtml(htmlString);

    // Create a new element to hold it
    var newElement = document.createElement('div');
    newElement.innerHTML = decodedString;
    // Replace this script with the new element
    var scriptElement = document.currentScript;   
    scriptElement.parentNode.replaceChild(newElement, scriptElement);

And for good measure, a nocode approach if you’re feeling lazy.
Downside here is performance. The decode happens after the page has loaded, so there is a brief delay before the decoded content will appear.

And I’d completely forgotten that I’ve written some of this up before-

1 Like

Hey Michael,

Thank you SO much for your super detailed and comprehensive answer.

I’ll considerate the different pros and cons of each option but looks like simply adding the SVG as an image on the CMS is what’s going to make more sense in this particular case. After all, it’s a photographer’s portfolio so it’s going to have loads of big images anyway and the weight of an extra SVG isn’t gonna make any difference.

And thanks also for the link to your articles!

1 Like