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.
<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);
})();
</script>
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-