Blazor WASM hosted as Azure Static Web App and how to handle direct links
Long time no post!
i have been busy trying to "lunch" my PWA app https://www.homeyummies.net , one of the challenges i faced was when i communicate direct links to the users like https://www.homeyummies.net/register that gave the user an Azure 404 page although it's a valid path on the Blazor WASM app, but as this is an SPA and routing is happening at client-side, when calling this directly the server looks for https://www.homeyummies.net/register/index.html and as it doesn't find it, it return 404.
a couple of google searches and i did find some solutions out there for that, and when trying to implement them i got a major issue, handling this issue can only be really tested after deployment as part of the solution do relay on what are you hosting the Blazor app on, i did try a couple of them but nothing really worked without issues!
but when i combined a couple of them together it did form a good solution for and i though to share it
so the solution have 3 parts:
1.Custom 404
first thing is to configure whatever you are hosting the Blazor WASM to server a custom 404 page, for my scenario that was Azure Static Web App service, you can find here that you need to have "staticwebapp.config.json" in app root so i added that file on my app wwwroot directory with this content
{
"responseOverrides": {
"404": {
"rewrite": "/404.html"
}
}
}
2.Custom 404 Code
now that we have the redirect it's time to create that 404.html file on your Balzor WASM app wwwroot folder, and do some magic there so it redirect the URL as a parameter to your app root, other solutions didn't take into account that URLs can have params and such, and i needed to redirect with all these included, this is why i choose to Base64 encode the URL, my 404.html ended up being
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Home Yummies</title>
<script type="text/javascript">
var l = window.location;
var relativeReturnUrl = window.location.pathname + window.location.search;
l.replace(
'/?returnUrl=' + btoa(relativeReturnUrl)
);
</script>
</head>
<body>
</body>
</html>
3.Index.razor code
Now that we got redirected to home page the server will respond and the Blazor WASM app will be loaded, we need now to get the "returnUrl" parameter value, decode it and redirect to it, which can be done with this code:
@using Microsoft.AspNetCore.WebUtilities
@inject NavigationManager _navigationManager
protected override void OnInitialized()
{
var uri = _navigationManager.Uri;
var queryString = _navigationManager.ToAbsoluteUri(uri).Query;
var queryParams = QueryHelpers.ParseQuery(queryString);
if (!queryParams.Any() || !queryParams.ContainsKey("returnUrl"))
{
base.OnInitialized();
return;
}
string returnUrl= queryParams["returnUrl"].ToString();
var base64EncodedBytes = System.Convert.FromBase64String(returnUrl);
returnUrl = System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
_navigationManager.NavigateTo($"{returnUrl}");
}
Now your Balzor WASM application hosted using Azure Static Web App should redirect any url to index and index should be able to take care of it