'What is the right way to prerender Blazor WebAssembly?
It almost works after the following steps:
- Install the hosted version of
blazorwasm
template app.dotnet new blazorwasm --hosted -o HostedWasm
- Copy
_Hosted.cshtml
fromblazorserver
template to thePages
folder. - Change
endpoints.MapFallbackToFile("index.html")
toendpoints.MapFallbackToPage("/_Host")
inStartup.cs
of the server - Change
<script src="_framework/blazor.server.js"></script>
to<script src="_framework/blazor.webassembly.js"></script>
in_Host.cshtml
Now if you dotnet run
the server you will be able to navigate template pages with prerendered HTML.
But, I have two questions:
- Is it the "right" way to do the prerendering of Blazor WebAssembly? I see nothing about this in the docs.
- How to share DI between server-side and client-side? Now, if you navigate
/
and then going to/fetchdata
everything will be fine, but if you then use F5 (e.g refresh) on/fetchdata
path, you will see
InvalidOperationException: Cannot provide a value for property 'Http' on type 'HostedWasm.Client.Pages.FetchData'. There is no registered service of type 'System.Net.Http.HttpClient'.
To fix it you need to copy HttpClient
configuration code from Client/Program.cs to Server/Startup.cs
Solution 1:[1]
Andrew Lock's excellent blog post, Enabling prerendering for Blazor WebAssembly apps, gives the best instructions, IMO. To repeat his steps here:
- Add _Host Page,
dotnet new page -o Pages -n _Host --no-pagemodel
- Copy Client/wwwroot/index.html into it, keeping
@page
at the top - Add tag helper,
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
- Replace
<div id="app">
with<component type="typeof(BlazorApp1.App)" render-mode="WebAssemblyPrerendered" />
- Remove
builder.RootComponents.Add<App>("#app")
from Program.cs - Add an http client to the server, e.g.
services.AddSingleton<HttpClient>
.
He goes on to link to other blog posts which debate the 'right' to handle the missing HttpClient problem. I think just injecting a client is the 'right' approach. It's a simple solution. The app is only running on the server for a few seconds. The pre-rendered app isn't interactive anyway, so it's not like the user is going to click around a bunch.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | James Coliz |