This was super helpful! I’ve recently encountered a project with a similar need, but I only wanted to render the image element if the CMS item has an associated image or URL in your case. The “conditional visibility“ functionality still dumps the <img> element into the DOM, even if the src isn’t set, which isn’t ideal for web accessibility.
I opted to make a cute little web component that will conditionally add the image to page.
All you need to do is this:
Add site-wide custom element code
class CmsImage extends HTMLElement {
static observedAttributes = ["source", "alt"];
constructor() {
super();
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === "source" && newValue) {
const image = new Image();
image.src = newValue;
this.appendChild(image);
}
if (name === "alt" && newValue) {
const image = this.querySelector("img");
if (image) {
image.alt = newValue;
}
}
}
}
customElements.define("cms-image", CmsImage);
Then, anywhere you need to conditionally render and image you can use that <cms-image> web component, you just drop a Code Embed element on the page with the necessary attributes:
<cms-image source="" alt=""></cms-image>
Then you can click the little “+ Add Field“ button to put the CMS data in those two attributes. It should look something like this:
The nice parts about this approach is:
- The image doesn’t end up in the markup unless the CMS has the data.
- It works with both text url fields and CMS image fields.
The drawbacks are:
- You don’t get the image optimization functionality that comes out of the box with Webflows image element. I didn’t need that in this case.
So far, JavaScript web components are the most elegant way I’ve found to actually conditionally render pieces of markup from a CMS. It works pretty well in conjunction with Webflow’s components.
