17:27 0 0
How to enable prerender in Blazor WebAssembly App

How to enable prerender in Blazor WebAssembly App

  DrUalcman |  noviembre 42023

Today I would like to talk about Blazor Prerender. Also my apologies if my english it's not very good, I am not usually write in English and my first language it's Spanish.

Why I will talk about prerender? One of the "invoncenients" when use a Blazor WebAssemgly App, it's the first load of the page. Browser need to download all the diles and this can take time. Depends how big is our app, can take too much time. So, to avoid the anoying Loaging is when we can use preloading. Also preloading helping us to improve the SEO in the page, because robots can see the apge already rendered with all the data, so no troubles about personalize SEO en blogs pages, for example. Let's start.

Enable prerender in Blazor WebAssembly App

First we need some server application where we can host our Blazor webAssembly App. I will use in this post a simple AspNetCore Web Api using, Minimal Api.

1: Add into the Web Api a nuget Microsoft.AspNetCore.Components.WebAssembly.Server

2: Delete this lines in the Program.cs from the Blazor Client

builder.RootComponents.Add< App >("#app");
builder.RootComponents.Add< HeadOutlet >("head::after");

3: Add reference to Blazor Client into Web Api. Obvious, isn't it? We need render this App from the Web Api.

4: Add a file _Host.cshtml to our Web Api. This file it's the same kind of file if you create a Blazor Server App. you can copy from there and/or download from here the file already prepared.

5: In this file, change the namespace with the namespace about our Web Api

6: Add a reference to the namespace about our Blazor Client, @using Blazor.Client

7: Update links about ajutogenerated CSS file with the namespace about our Blazor Client

< link href="[Blazor Client namespace].styles.css" rel="stylesheet" / >

Or any other you are using into the Blazor Client. You almost need to replicate what do you have in the file index.html into this new file. Download here.

8: Change the framwork javascript, if you copy from Blazor Server App, to use the webassembly.

< script src="_framework/blazor.server.js" >< /script >

9: in the Wb Api need to prepare to use and render razor pages, so add the service

builder.Services.AddRazorPages();

10: Now we nees to use all the necesary services to render static pages and Blazor pages.

app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.MapRazorPages();

11: Last step. We need to execute our root page.

app.MapFallbackToPage("/_Host");

12: If you are using some Web Api template, possible need to remove the start page into the launchSettigs.json file. So search the entrance "launchUrl" and remove the content to start the WebApi from the root page.

That's all. You can run now your application and you can see don't have the Loading anymore.

Considerations

If you have services registered in the Blazor Client, and this services are necesary in the first time when page is load, I mean, if user access directly to the url, then this services it's necessary to register also in the Web Api, because if not can't render the page. Example, HttpClient it's used in the demo page quering in the Api.

To fix that, we can add this code into the Web Api.

builder.Services.AddSingleton(sp =>
        {
            // Get the address that the app is currently running at
            var server = sp.GetRequiredService< IServer >();
            var addressFeature = server.Features.Get< IServerAddressesFeature >();
            string baseAddress = addressFeature.Addresses.First();
            return new HttpClient { BaseAddress = new Uri(baseAddress) };
        });

Hope you can do all and enjoy the prerender.

Actualizacion 9 diciembre 2024

Si estas utilizando un Action < HttpClient > en tu servicio, es posible que no puedas utilizar el AddSingleton como te estaba sugiriendo, otra posibilidad que tienes para hacer obtener de forma dinamica la direccion de la api sería.

builder.Services.AddBackendServices(
client =>
{
var baseAddress = builder.Configuration["ASPNETCORE_URLS"];
if (!string.IsNullOrEmpty(baseAddress))
{
string[] addresses = baseAddress.Split(';', StringSplitOptions.RemoveEmptyEntries);
client.BaseAddress = new Uri(addresses[0]);
}
else
{
client.BaseAddress = new Uri("https://localhost/");
}
});
Y tu servicio estaría esperando algo como esto. En caso, poco probable de no recibir anda, como tu cliente necesita una direccion base para trabajar, pue se le envia un localhost que bueno, probablemente devuelva error de no encontrado, pero al menos no se rompera el codigo.

class Repository(HttpClient client)
De esta manera tu servicio estará recibiendo siempre una dirección base con la misma dirección que tu API.

¿Porque un array de direcciones?

Basicamente porque en la variable de configuracion ASPNETCORE_URLS nos puede venir una lista de direccion como "https://localhost:7126;http://localhost:5037" o las que se tengan configuradas en tu servidor web.


0 Comentarios

 
 
 

Archivo