dotnet / dotnet/aspnetcore

[Blazor] Application models

Open
#51,579 0 comments 0 reactions 0 assignees View on GitHub
area-blazor Docs
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

Describe the ways in which interactivity can be added to an existing app and the trade offs for each option. A rough sketch is below:

# Blazor web application models

Blazor web is the new version of the ASP.NET Component model that extends the capabilities of the current Blazor Server and Webassembly applications with support for Server Side Rendering (also known as prerendering) and traditional server side features like form handling.

Blazor web enables developers to render the entire UI using just Blazor components. This means that you don't need a root HTML or _Host.cshtml page as you did in Blazor WebAssembly and Blazor Server, and instead you can render the entire UI using just components.

Blazor Web integrates with ASP.NET Core's routing and middleware to enable features like form handling, authentication, authorization, and more. Routing and navigation in Blazor Web applications happens server side by default, although you can also use client side routing.

Whether the app uses server-side routing or client-side routing is up to the app. The main difference between the two approaches is whether app state is preserved across pages.
* With server-side routing, app state is not preserved across pages, which means that when you navigate to a different page, for example, by clicking a button, any state in memory is lost1.
* With client-side routing, app state is preserved across pages, which is the

_1: The state in memory might be preserved when using enhanced navigation and the runtime remains loaded, but this is not guaranteed and should not be relied upon._

## Apps with server-side routing

This is the default for new Blazor Web applications. The majority of the apps do not require a high degree of interactivity that justifies using Blazor WebAssembly and Blazor Server, they can instead be handled through static server side rendering as many sites and applications did in the past.

It is for this reason that it makes sense for routing to happen on the server (as doing it client-side inmediately requires a webassembly runtime or a SignalR connection). Instead, we think it is better in general to render the UI server-side in most situations and rely on interactivity on specic pages that benefit form it.

```mermaid
sequenceDiagram
participant User
participant Browser
participant Server
Browser->>Server: Request for '/'
Server->>Server: ASP.NET routing middleware (find endpoint for '/')
Server->>Server: Render root component for endpoint '/' (Typically App.razor, the equivalent of rendering _Host.cshtml)
alt Router component rendered inside App.razor
Server->>Server: Router component render page identified for '/'
end
Server->>Browser: HTML for '/'
alt App.razor rendered blazor.web.js
Browser->>Server: initialize interactive components
end
User->>Browser: clicks on a link to '/counter'
Browser->>Server: Request for '/counter'
Server->>Server: ASP.NET routing middleware (find endpoint for '/counter')
Server->>Server: Render root component for endpoint '/counter' (Typically App.razor, the equivalent of rendering _Host.cshtml)
alt Router component rendered inside App.razor
Server->>Server: Router component render page identified for '/counter'
end
Server->>Browser: HTML for '/counter'
alt App.razor rendered blazor.web.js
Browser->>Server: initialize interactive components
end
```

## Apps with client-side routing

This model can be thought as the evolution of the current Blazor Server and Web assembly models, as its in essence an improved version of that model that enables better prerendering. To understand the difference here is what a Blazor WebAssembly or Blazor Server app worked like, and here is how a Blazor Web app works in comparison.

```mermaid
sequenceDiagram
participant User
participant Browser
participant Server
Browser->>Server: Request for '/'
Server->>Server: ASP.NET routing middleware (match fallback route '{**path:nonfile}' and return index.html for webassembly or render _Host.cshtml for Blazor Server)
Server->>Browser: HTML for '/'
alt WebAssembly
Browser->>Browser: blazor.webassembly.js initializes interactive components
else Blazor Server
Browser->>Server: blazor.server.js initializes interactive components by creating a circuit,
which is a "stateful session" between the browser and the server via a SignalR connection.
end
User->>Browser: clicks on a link to '/counter'
alt WebAssembly
Browser->>Browser: blazor.webassembly.js intercepts the navigation and the client-side router renders a new page in response
else Blazor Server
Browser->>Server: blazor.server.js handles navigation by sending a message to the server and the "interactive" router component handles the navigation and produces a new render in response.
end
```

In contrast, here is how a Blazor Web app works with either an interactive webassembly or server router:

```mermaid
sequenceDiagram
participant User
participant Browser
participant Server
Browser->>Server: Request for '/'
Server->>Server: ASP.NET routing middleware (match endpoint for a given request and render root component (typically App.razor))
Server->>Server: App.razor renders a component that defines the render mode (typically Routes.Razor) which inside contains a router component
Server->>Server: Router component reuses the results from the ASP.NET routing middleware to render the page for '/'
alt WebAssembly
Browser->>Browser: blazor.webassembly.js initializes interactive components including the router component
else Blazor Server
Browser->>Server: blazor.server.js initializes interactive components including the router
end
User->>Browser: clicks on a link to '/counter'
alt WebAssembly
Browser->>Browser: The router component running on the page intercepts the navigation and renders a new page in response.
else Blazor Server
Browser->>Server: The router component running on the page intercepts the navigation,
sends a message to the server and the "interactive" router component handles the navigation and produces a new render in response.
end
```

With this in mind, the main differences between the old model and the new model are:
* Prerendering doesn't use a fallback route. Instead, it can use the page information on the app components to decide what routes to handle. This is useful as it avoids incorrectly serving HTML for missing endpoints.
* The app is completely prerendered using Components, without the need for an additional index.html page or a _Host.cshtml page to produce the top level wrapping HTML of the interactive components.
* With webasembly, prerendering becomes much easier, as the app is already setup to do so.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.