lamplightdev

How to show different fallback content with Web Components

Thu Apr 23 2020

With web components there's often a need to render fallback content - both to show content in browsers that don't have support for web components (or with JavaScript disabled/broken) and to show content to the user while the web component is being loaded/initialised. The trouble is that we probably want to display different fallback content in these two scenarios - perhaps alternative static content in the first case and a loading indicator in the latter.

Fallback content is provided by supplying HTML between our custom element tags, but how do we have 2 different version of fallback content?

To achieve this we first build our component as normal:

class WCExample extends HTMLElement {
constructor() {
super();

this.attachShadow({ mode: 'open' });
}

connectedCallback() {
this.render();
}

render() {
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
padding: 1rem;
color: steelblue;
border: 1px solid steelblue;
}
</style>

<p>Loaded and ready to go!</p>
`
;
}
}

customElements.define('wc-example', WCExample);

Next we provide our two versions of fallback content inside out new element, providing different classes to each:

<wc-example>
<p class="no-wc">A static version of the content</p>
<p class="has-wc">Please wait...</p>
</wc-example>

If we were to load this HTML in the browser we'd see both versions of the fallback content until the component code is loaded. However if we apply a class to the body indicating no web component support, .no-wc, and immediately remove it just after the body tag if web components are supported (before the component code is loaded or the component tag is rendered):

if (window.customElements) {
document.querySelector('body').classList.remove('no-wc');
}

The body will then only have the .no-wc class if JavaScript has run and Web Components are supported. We can then control which version is displayed with a couple of global CSS rules:

body.no-wc .has-wc {
display: none;
}

body:not(.no-wc) .no-wc {
display: none;
}

See this in action here (with an artifical delay applied to the loading of the Web Component code). Be sure to test with and without JavaScipt enabled to see the difference.


Get the latest Web Component news, tips and advice

I send out a regular newsletter - Web Component Bytes - containing curated news, tips and advice about Web Components.

Sign up below to get it hand delivered to your inbox - no spam, and unsubscribe at anytime.