The issue
I agree with a lot of people that updates are a requirement that needs to be resolved as quickly as possible by end-users. The updates have patching for security, performance, or any other matter where an end user only benefits off.
Reality, it doesn’t always happen. People stall on old versions, broken versions, or even unsupported versions. Browsers are no different, think about the shockwave that came when Microsoft announced the end of support for internet explorer. For years, people could switch to Edge but remained on internet explorer for any valid reason they could come up with. Companies that I consulted in the past weren’t even on the latest version of internet explorer.
That being said, when companies want their app written as an Blazor Web Assembly application, this is a pain. Because it requires a modern browser that supports Web Assembly, obviously. But, what about all those users with an outdated or former browser that don’t support Web Assembly. Will they be able to load or see anything?
Simply no, when a user navigates to that Blazor Web Assembly application with one of those outdated or former browsers, it will give them a blank page with the global set error message. Wich is in my opinion a horrible thing, because end users don’t get any feedback on whats happening except that ‘something’ went wrong. “No shit Sherlock”. In this case, we can make this process a bit more UX friendly and guide users into resolving it because they are able to fix it themselves by just updating their browser or installing a new one.
Understanding why
Before going into the work around, first lets understand why end users get a blank page. A Blazor WASM application starts off with the basic index.html. It’s the only page that starts it all. (If you want a quick step through on how your application loads, I will add a new blog shortly about this. So, come back soon.)
Your Html contains the script <script src="_framework/blazor.webassembly.js"></script>
that is used to start your blazor application. This script has an autostart function, when the page is loaded it will start your Blazor WASM app. When it fails in doing so, it will throw it’s exception to the div tag identified as ‘blazor-error-ui’. In most applications this is the same greenfield text stating ‘An unhandled error has occurred’ with a reload button.
The fix
- In your index.html you can easily stop that autostart and create a cold start of your blazor application by simply setting the autostart to false.
<script src="_framework/blazor.webassembly.js" autostart="false"></script>
By doing so, keep in mind that you will have to trigger the start of the blazor application yourself.
Next, add below Js function that checks if the browser has support for Web Assembly. This function checks if it can find Web Assembly, if it can be instantiated and checks if an instance can be started.
<script>
window.webassemblySupported = (function () {
try {
if (typeof WebAssembly === 'object'
&& typeof WebAssembly.instantiate === 'function') {
const module = new WebAssembly.Module(
Uint8Array.of(0x0, 0x61, 0x73, 0x6d,
0x01, 0x00, 0x00, 0x00));
if (module instanceof WebAssembly.Module)
return new WebAssembly.Instance(module)
instanceof WebAssembly.Instance;
}
} catch (e) {
}
return false;
})();
</script>
Next, starting our Blazor application or redirect the user to a custom page (fe. unsupportedbrowser.html) where you can set a clear message that their browser is unsupported and add links to all modern browsers that support Web Assembly.
<script>
if (webassemblySupported) {
Blazor.start({});
}
else {
let getUrl = window.location;
let baseUrl = getUrl.protocol + "//" + getUrl.host + "/";
window.location = baseUrl + "unsupportedbrowser.html";
}
</script>
When your app is browsed to, using an ‘outdated browser’, users will now get a clear exception page that states that their browser should be updated, or they require a more modern browser than the one their using. It’s that simple. These steps could easily be extended with more scenarios, think about cases like downloading boot resources from a specific server, preliminary device authentication, chaining tasks to the manual starts promise, …
In Blazor server you can also extend the chain in this same way, only then it is <script src="_framework/blazor.server.js" autostart="false"></script>
For more information see the documentation on Microsoft.
That’s it, fun times.
Save, commit, and deploy.