Explain Codes LogoExplain Codes Logo

How to fallback to local stylesheet (not script) if CDN fails

javascript
fallback
stylesheets
error-handling
Anton ShumikhinbyAnton Shumikhin·Jul 22, 2024
TLDR

To handle CSS fallbacks, use the <link> tag's onerror attribute. This fires a function to fetch a local stylesheet in case of a CDN failure.

<link rel="stylesheet" href="//cdn.example.com/style.css" onerror="this.href='local-style.css'; this.onerror=null;">

Upon CDN failure, onerror swiftly switches the href to point to your local file, ensuring uninterrupted styling. Including this.onerror=null is vital to prevent multiple fallback attempts if even the local file fails.

onerror—Your Sleek Knight in Shining Armor

Besides replacing href, you can also dynamically append another stylesheet using JavaScript. This method offers expanded control, enabling multiple level fallbacks or comprehensive error handling.

// The Fallback Hero. function loadFallbackStyleSheet() { var head = document.getElementsByTagName('head')[0]; var link = document.createElement('link'); link.rel = 'stylesheet'; link.href = 'local-style.css'; // Local Knight ready for rescue. head.appendChild(link); // Sending the rescue squad. } var link = document.createElement('link'); link.rel = 'stylesheet'; link.href = '//cdn.example.com/style.css'; // Knight #1 enters the battlefield. link.onerror = function() { loadFallbackStyleSheet(); // Oh no, Knight #1 is down! Send backup! this.onerror = null; // We don't have any more knights :'( }; document.getElementsByTagName('head')[0].appendChild(link);

This carefully placed script hails the local stylesheet to the <head> element upon detecting a CDN load failure.

The Art of Detecting Successful Load

Another course of action involves validating stylesheet load success by creating a test rule in your stylesheet and verifying if it applies.

#cssTestElement { display: none; } ... #cssTestElement { display: block; /* Assumes CDN Knight won the battle, otherwise, prepare backups */ }

In JavaScript:

window.onload = function() { var testElement = document.createElement('div'); testElement.id = 'cssTestElement'; document.body.appendChild(testElement); if (window.getComputedStyle(testElement).display === 'none') { loadFallbackStyleSheet(); // The test rule failed, deploy the backups! } };

This method checks for a specific rule from the CDN stylesheet when the page loads. This ensures a false positive is not raised due to stylesheet prefetching.

Roll Back to Alternative Fallback Methods

Swift DOM Reload After CDN Defeat

Should the CDN lose the battle as indicated with .cssRules or .rules compatibility checks, dynamically load local resources as reinforcements:

if (!link.sheet || !link.sheet.cssRules.length) { // Disaster! CDN has been defeated. Call for local reinforcements! loadFallbackStyleSheet(); }

Combat Guide for a Serene User Experience

  1. Overcome browser discrepancies: Check fallback behavior across various browsers. Some browsers might show distinct behaviors when executing error handlers.

  2. Prepare for consistent network conditions: On occasions, even if network restores quickly, failover might trigger. Equip with strategy by implementing timeout delays or additional verification checks.

Employing Forces like jQuery

With jQuery, you can simplify your dynamic loading code:

$('head').append('<link rel="stylesheet" href="local-style.css" type="text/css" />');

Remember, this trick will only work if jQuery itself is being served locally or if you're certain of its availability.