Featured resource
2025 Tech Upskilling Playbook
Tech Upskilling Playbook

Build future-ready tech teams and hit key business milestones with seven proven plays from industry leaders.

Check it out
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

Guided: Exploring Blazor's Hosting Models

.NET 8 has ushered in an array of exciting new features, notably enhancing Blazor hosting capabilities. This lab offers a hands-on experience with configuring a versatile .NET 8 Blazor application. You'll learn to seamlessly integrate Blazor Server, Blazor WebAssembly, and the innovative Blazor Server-Side Rendered components into a unified application.

Lab platform
Lab Info
Level
Beginner
Last updated
Dec 22, 2025
Duration
30m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use, and consent to receive marketing emails from Pluralsight.
Table of Contents
  1. Challenge

    1. Introduction

    Welcome to the lab:

    Guided: Exploring Blazor's Hosting Models.

    What's New in .NET 8

    Since 2019, ASP.NET's Blazor has enabled C# developers to extend their expertise to front-end development in web-based applications.

    With the launch of .NET 8, Blazor introduced a third rendering mode known as Server-Side Rendering (SSR). This option fully processes the component on the server, rendering it to HTML, and sending just that HTML back to the client.

    Additionally, Blazor now allows for the rendering mode to be declared at the component-level, rather than globally for the entire project.

    This significant advancement enables individual components to select the most suitable hosting model for their specific requirements.

    Options include: Blazor Server for robust client interactions, Blazor WebAssembly for complete client-side execution, and the new SSR for improved performance and enhanced SEO.

    What to Expect

    In the upcoming steps, you'll learn how to configure a simple Todo component to operate under each of these rendering modes.

    You'll see firsthand how each mode offers unique benefits and trade-offs to developing your components.

    No Prior Knowledge This lab is designed with the assumption that you have a basic understanding of Blazor. Therefore, some implementation details may not be explored in depth.

    If you are new to Blazor or Razor syntax, you are encouraged to proceed. You can be confident that all of the major points will be addressed thoroughly.

    To continue the lab, click the right arrow.

    If you are interested, following is an expanded history of Blazor's evolution.

    📰 Blazor's History **** ### Blazor Server

    Launched in 2019 with ASP.Net Core 3.0, Blazor Server emerged as a pivotal development for .NET enthusiasts. It shifted the paradigm of web application development from a JavaScript-centric approach to leveraging C# capabilities.

    This was accomplished by utilizing a persistent SignalR connection, enabling seamless communication between the browser and the server. User interactions are processed server-side in C#, with updates dynamically reflected on the client's browser, illustrating real-time web functionality

    Blazor WebAssembly

    The subsequent year ASP.NET Core introduced Blazor WebAssembly. This innovation transformed the landscape of web development by allowing entire applications to be hosted entirely in the client's browser.

    Written in C# and compiled into WebAssembly, this approach empowered the execution of .NET code directly in the browser, freeing it from server-side dependencies. This breakthrough provided a robust alternative to traditional JavaScript frameworks, enabling developers to construct rich, interactive UIs entirely in C#.

    Blazor Server-Side Rendering (SSR)

    With .NET 8's release, a novel rendering mode, Blazor Server-Side Rendering (SSR), was introduced. This mode involves server-side component rendering into HTML, akin to Razor Pages or MVC, but with the added advantage of Blazor's component-based architecture. Key features like Stream Rendering and Enhanced Navigation further augment this mode's capabilities.

    Component Level Rendering

    A significant advancement in .NET 8 is the component level declaration of different rendering modes within a single project. This flexibility contrasts with earlier versions, where a singular hosting model was a project-wide commitment.

    For example, straightforward pages like About or Home can be efficiently rendered server-side, while complex, interactive elements can coexist on more dynamic pages. This approach offers a strategic solution to the complexities previously associated with client interactivity in web applications.

  2. Challenge

    2. Getting Started

    Overview

    Before getting started, take a moment to get familiar with the lab's interface.

    ℹ️ Lab Environment **** #### Explorer Tab The filesystem is accessible using the **Explorer** tab identified with the stacked paper icon at the top left. You can open this tab whenever you need to interact with the project files.

    Source Control

    This lab utilizes source control to assist you in navigating changes to files.

    Should you encounter any difficulties with a specific step, you can access guidance through the Source Control tab on the left, which is marked with a branch icon.

    Within the main branch, you'll find the final state of each file. This allows you to either open the changed file to view the necessary changes or simply use the back arrow to revert the file to its final state.

    ⏯️ Running the Project To start running the project, click on the `watch` task link. This command will start the project and will also automatically rebuild the project whenever you make changes. > If you ever see an error message in the **Terminal** window, you can always just click the **watch** link again to restart the project.

    Once the project is running, you can click to open the application in a new browser window:

    Open Application: {{localhost:5200}}

    .NET's hot reload feature is currently turned off, you will need to manually refresh the browser window to see your changes.

    Application Overview

    Once you have refreshed the browser, you will find several tabs on the left side, which will be used to link to the various versions of this component.

    Note that depending on the browser window's width, you may need to first click on the three line icon in the upper right corner.

    For now, click on the Todo - SSR tab to see the basic layout of the todo component.

    Take a moment to notice the key features of the component, and some missing functionality:

    1️⃣ Undone Todo Count **** The count to the right of the **Todo (1)** header indicates the number of tasks that are not marked as complete.
    2️⃣ Todo Entry **** In the **Something todo** entry field, feel free to enter a task and click **Submit**.

    If you try to add a second time, you'll notice that your previous entry is replaced by the new one.

    3️⃣ Checkbox Completion **** Try clicking the checkbox next to any item to mark it as completed. Observe that the undone count does not update when you do this.

    In the upcoming steps, each of these areas will be addressed, providing insights into the trade-offs to consider when choosing a particular rendering mode.

    Click the right arrow to begin configuring the Server-Side Rendering version of the Todo component.

  3. Challenge

    3. Overview of an SSR Component

    Overview of an SSR Component

    Static Server-Side Rendering (SSR) fully renders the logic of a .razor component on the server and sends the static HTML back to the client.

    🔀 SSR Trade-offs **** With the release of .NET 8, **Static Server-Side Rendering (SSR)** has been established as the default rendering mode.

    Unless configured otherwise, a .razor file will be rendered using SSR, with the resulting static HTML sent to the client.

    This introduces a trade-off of:

    No Client Interactivity

    Consequently, once the page reaches the client, it can no longer interact directly with the application's C# logic, a distinguishing feature of Blazor, until now.

    But, No Overhead and SEO Friendly

    On the other hand, this approach reduces the overhead typically associated with other rendering modes, thereby enhancing performance. Additionally, the use of plain HTML is beneficial for optimizing SEO.

    For example, this method eliminates the need for the continuous SignalR connection that Blazor Server requires and bypasses the necessity to download WebAssembly packages, as is the case with Blazor WebAssembly.

    Code Review

    To explore how this SSR component is configured: Open the TodoSSR.razor file. Identify where the three main elements mentioned earlier are defined.

    *️⃣ Undone Todo Count **** Starting with the count of undone tasks, which can be seen within the `

    ` tag, you'll encounter the first trade-off of using the **SSR** rendering mode.

    Notice the inline Razor expression used to retrieve the number of undone TodoItems in the todos list.

    While this expression effectively populates the count of current todo items during rendering, it won't update in real-time on the client side. Instead it will only change upon the next page refresh, such as when you create a new todo item.

    *️⃣ Todo Entry Form **** Next, consider the `` component.

    This component serves as a convenient tool for constructing an HTML form and seamlessly integrating it with your component's logic.

    However, the page is still rendered as a basic HTML form on the client-side, which needs to submit changes back to the server, similar to a traditional request/response model.

    This process currently results in a full page refresh. Though you will soon discover some convenient functionality that Blazor has developed to mitigate this.

    *️⃣ List of Tasks **** Immediately following the `` is a Razor conditional statement that reacts to the current status of the `todos` collection. Displaying whether there are any todo items or not.

    Though you may be wondering about the first Loading message. If SSR always returns static HTML, you might be curious when the Loading text would appear to the client.

    The answer lies in a key feature of Blazor SSR called stream rendering, which will be addressed in the next step.

    To continue learning more about SSR's stream rendering, click on the right arrow.

  4. Challenge

    4. Configuring SSR's Stream Rendering

    Stream Rendering

    Traditional web-based applications often face common issues such as: slow response times for longer processes, the need for page refreshes during client interactions, and challenges like maintaining client scroll positions.

    While SSR primarily renders static HTML pages, stream rendering has been introduced to offer a more dynamic user experience.

    The following steps will guide you through implementing these features.

    🔎 Provided Configurations **** Before digging into any configurations you will need to make, you may be interested in seeing what configurations have already been provided for you.

    Program.cs Configuration

    To see how an SSR project has been configured you can:

    Open the Program.cs file. Specifically look for the following two lines:

    builder.Services.AddRazorComponents(); 
    . . . 
    app.MapRazorComponents<App>();
    

    These two lines form the foundational configuration for an ASP.Net Blazor project, which by default includes support for Server-Side Rendering (SSR).

    In the subsequent steps of this lab, you will add to this configuration to incorporate functionality for the other hosting models.

    Blazor Javascript Framework

    In addition to the server configurations, Blazor also includes the blazor.web.js javascript framework.

    This framework helps to capture client side requests and process them through the configured hosting model.

    You can see the inclusion of this script file in the App.razor file.

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

    Now, for the configurations you'll need to add to the todo component to support stream rendering:

    1️⃣ Add the Stream Rendering Attribute **** To enable SSR's stream rendering functionality, simply add an attribute towards the top of the **TodoSSR.razor** file

    Just under the @page "/todossr" directive, insert the attribute:

    @page "/todossr"  
    @attribute [StreamRendering]
    

    Now, when you refresh the Todo - SSR page, you will initially see the Loading message and an empty Todo () count. Following the simulated delay, the page will update to display the final state.

    Speed up Testing In order to demonstrate this Loading message the Task.Delay() has been set to 2 seconds, feel free to lower this value if you would like to speed up your testing.

    2️⃣ Enhanced Navigation **** In addition to the temporary state, the **StreamRendering** attribute also offers **Enhanced** navigation functionality.

    This feature helps to mitigate some page refreshes and the loss of client scroll position, such as when posting a new todo item.

    Demonstrate the Issue

    To demonstrate this, you can push the todo entry form down the page, forcing you to scroll to this position.

    This can be achieved by inserting the following <div> above the <EditForm> component, adding a significant height:

    <div style="height:100vh" />
    <EditForm . . .
    

    After making this change, refresh the Todo - SSR page, scroll down to the todo entry form, create a new item, and then click Submit.

    You'll notice that the page refreshes and brings you back to the top of the page.

    Enhancing the User Interface

    With stream rendering enabled, you can prevent a full page refresh by adding the Enhance attribute to the EditForm component:

    <EditForm Enhance . . .
    

    After refreshing the Todo - SSR page, try adding another todo item. You'll notice that the item is added without the page flash or altering your position on the page.

    How does this work?

    In the SSR hosting model, although page requests adhere to the traditional request/response format, the blazor.web.js framework plays a critical role. It intercepts these requests, processes them in the background, and integrates any updates into the existing page.

    This approach significantly improves the user's experience despite that SSR pages are not as fully interactive as the other rendering modes.

    3️⃣ Interactivity Limitations **** Enhanced stream rendering has significantly improved the user experience compared to plain HTML. However, there are still some functionality issues with the current component. For example, newly added items overwrite the previously added ones, and the **TODO ()** count does not dynamically update as items are checked off as complete.

    These issues could be addressed with additional logic. At this stage, it’s crucial to weigh the trade-offs: deciding whether to continue refining the SSR component to suit current requirements or to switch to another hosting model, like Blazor Server, to take advantage of its features.

    Feel free to take a moment to consider how you might optimize the current SSR component to meet the requirements.

    The transition to the Blazor Server rendering mode will be explored in the next step, whenever you're ready to proceed.

    Click on the right arrow to explore how to configure a component for the Blazor Server rendering mode.

  5. Challenge

    5. Configuring Blazor Server

    Configuring the Blazor Server

    Blazor Server, the original hosting model, enables direct interaction between the client and the server-hosted C# logic. This is interaction is facilitated through a persistent SignalR connection with the server.

    🔀 Blazor Server Trade-offs **** #### Open SignalR Connection

    The main trade-off to consider when choosing the Blazor Server rendering mode is the need for the server to maintain an open SignalR connection for every client accessing your application.

    But, Enhanced Client Experience

    However, the enhancements to client interactivity provided by this model may well justify this trade-off.

    🗒️ Component-level Rendering **** With the introduction of component-level rendering declarations, you have the flexibility to decide which components use this resource-intensive model.

    A resource intensive Blazor Server component can be separated from other components that can easily be rendered through SSR

    While server resource considerations remain important, their impact can be moderated based on the anticipated usage of the individual components, rather than the entire application.

    1️⃣ Configuring the Project **** To begin using **Blazor Server**, the project needs to be configured to use the interactive server.

    This can be accomplished by adding options to the two configurations previously seen in the Program.cs file of the BlazorHosting project.

    Add the interactive server components to the available services towards the top of the Program.cs file

    That line should now look like:

    builder.Services.AddRazorComponents()
        .AddInteractiveServerComponents();
    

    Then towards the bottom of the file, add the interactive server render mode to the project.

    app.MapRazorComponents<App>()
       .AddInteractiveServerRenderMode();
    

    New Blazor Template

    With this new releases, .NET 8 has also introduced a new project template for blazor.

    Among the flags for this template is also the -int, --interactivity flag. This option allows you to declare what rendering modes will be supported by your project.

    Passing in the flag -int Server will automatically make the above configurations for you.

    The other -int options are:
    None - Supports only SSR
    Server - Supports SSR and Blazor Server
    WebAssembly - Supports SSR and WebAssembly
    Auto - Supports all rendering modes

    2️⃣ Configuring the Component **** Now that the project is configured to use **Blazor Server**, you can begin configuring your page components to utilize this rendering mode.

    Add the following line, at the top of the TodoServer.razor file just under the @page "/TodoServer" directive.

    @page "/TodoServer"
    @rendermode InteractiveServer
    

    Review Changes

    Navigate to the Todo - Server page and experiment by adding several todo items and checking some as done. You'll notice the page now functions as expected.

    This level of functionality is enabled by the persistent SignalR connection. This connection retains the client's state on the server allowing for dynamic interaction with all page elements, but not limited to just the inputs within a form.

    Take a moment to compare the differences between these two razor pages. Pay special attention to how the Blazor Server pages interact with <input> elements, regardless of whether they are placed inside forms.

    Feel free to experiment with this Blazor Server render mode. You might also try adding the @rendermode InteractiveServer attribute to the top of the Todo - SSR page. This will demonstrate how easily the rendering mode can be changed for any page.

    When you're prepared to explore the Blazor WebAssembly hosting model, click the right arrow to proceed.

  6. Challenge

    6. Configuring Blazor WebAssembly

    Configuring Blazor WebAssembly

    Blazor WebAssembly represents another rendering mode that allows an interactive client application to be developed using C#.

    Contrasting with Blazor Server, which relies on an active SignalR connection, Blazor WebAssembly compiles the C# logic into a WebAssembly package. This package is then installed and ran directly within the client's browser.

    🔀 WebAssembly Trade-offs **** When considering **Blazor WebAssembly**, it's important to be aware of its trade-offs:

    Delay Waiting to Download

    Before the application can run in the client's browser, the entire package — which includes all client application logic and supporting frameworks — needs to be downloaded to the client's browser. The file size, influenced by the application's complexity, can be significant. This might lead to a delay before the user is able to see any content.

    But, No Active Connection

    Despite this possible delay, a notable advantage is that, once the application is loaded into the browser, there is no need for the client to maintain a constant connection to the server.

    Though, No Direct Connection

    Though this also means that it does not have direct interaction with the server-side logic. All interactions with the server must therefore be managed through API calls. This aspect necessitates careful architectural planning for the application.

    1️⃣ Creating the Client Project **** When adopting the WebAssembly rendering mode, creating a separate client project is essential. This project will encapsulate all the application logic destined for the client's browser, ensuring that the WebAssembly package contains only what is necessary.

    Opening the Explorer tab, you will find that this solution already includes a BlazorHosting.Client project. Within this project, the TodoWasm.razor file is provided containing logic similar to what you've been working with so far.

    2️⃣ Referencing the Client Project **** Before the **BlazorHosting** project can serve components declared in the **BlazorHosting.Client** project, it needs to be properly configured to recognize the client project.

    This involves not only adding the client project as a reference but also referencing the client project's assembly in the BlazorHosting's Program.cs file.

    At the bottom of the Program.cs file, right after adding the interactive server render mode, include a reference to the client project assembly as follows:

    app.MapRazorComponents<App>()
        .AddInteractiveServerRenderMode()
        .AddAdditionalAssemblies(typeof(TodoWasm).Assembly);
    

    Expectations

    With just this configuration, any .razor pages declared in the client project can be rendered using SSR.

    There are a couple more configurations required to be able to support Blazor WebAssembly

    3️⃣ Configuring the Project **** Similar to **Blazor Server**, **Blazor WebAssembly** also requires configuration within the `Program.cs` file of the **BlazorHosting** project.

    At the beginning of the Program.cs file, incorporate the interactive WebAssembly components into the available services with the following code:

    builder.Services.AddRazorComponents()
        .AddInteractiveServerComponents()
        .AddInteractiveWebAssemblyComponents();
    

    Then, towards the end of the file, include the interactive WebAssembly render mode. This should be added in conjunction with the additional assemblies that you've previously specified:

    app.MapRazorComponents<App>()
       .AddInteractiveServerRenderMode()
       .AddInteractiveWebAssemblyRenderMode()
       .AddAdditionalAssemblies(typeof(TodoWasm).Assembly);
    

    Multi Rendering Mode Support In this example, all three hosting models - SSR, Blazor Server, and Blazor WebAssembly - are configured for use in this application.

    Alternatively, you have the option support SSR in conjunction with either Blazor Server or Blazor WebAssembly. Remember, SSR is always available as the default option.

    4️⃣ Configuring the Component **** Now that the project is configured for WebAssembly rendering, you can start configuring your components to take advantage of this rendering mode.

    Open the TodoWasm.razor file, then locate the @page "/todowasm" directive. Just below that line, add the following rendermode attribute

    @page "/todowasm"
    @rendermode InteractiveWebAssembly
    
    🔎 Review the Page **** Navigate to the **Todo - WebAssembly** page and experiment by adding several todo items and checking some as done. You'll notice the page functions just like the **Blazor Server** version, though all logic is running within the browser.

    Pre-Rendering

    You may notice a slight change in the interface, particularly the addition of a Render Mode indicator at the top of the page.

    When you refresh the page, you will see that this briefly states Server Rendered before switching to WASM Rendered.

    This behavior is a result of page pre-rendering, a process that will be explained further.

    🔎 Pre-Rendering Considerations **** As demonstrated by a page refresh, there seems to be an intermediate stage where the WebAssembly page briefly retrieves information from the server before fully transitioning to the WebAssembly package.

    Upon reviewing the TodoWasm.razor file, you will find a reference to the ISharedService. Further examination of the Program.cs files in both the BlazorHosting and BlazorHosting.Client projects reveals that each project injects its own version of this service. BlazorHosting/Services/ServerService.cs and BlazorHosting.Client/Services/WASMService.cs for their respective projects.

    Initially, when the page is requested, the server provides a pre-rendered (non-interactive) page to quickly display something to the user. Following this, the actual WebAssembly application takes over.

    This behavior was also present in Blazer Server, though it was less apparent in that context.

    If the initial pre-rendering stage is not desired, you can suppress it by modifying the @rendermode attribute in the TodoWasm.razor file as follows:

    @rendermode @(new InteractiveWebAssemblyRenderMode(false))
    

    With this modification, when you refresh the page, the intermediate pre-rendering stage is bypassed, allowing only the WebAssembly application to respond directly to the client.

    Click on the right arrow to learn about the fourth rendering mode.

  7. Challenge

    7. Interactive Auto Rendering

    Interactive Auto Rendering

    You may have observed that there is one more @rendermode that has not yet been addressed.

    The last rendering mode option is @rendermode InteractiveAuto. This mode tries to combine the benefits of Blazor Server's quick response, with the fully client hosted Blazor WebAssembly.

    When a user initially visits a page marked as InteractiveAuto, the server renders the page using Blazor Server while simultaneously downloading the WebAssembly package in the background. During this initial visit, the component operates as a Blazor Server component, utilizing the SignalR connection. Upon the user's subsequent visit to this page, it will be rendered using Blazor WebAssembly.

    🔀 Auto Trade-offs **** The Auto rendering mode is designed to rapidly provide users with an interactive page while ultimately leveraging the WebAssembly rendering mode.

    Duplicated Processes

    However, a key trade-off to consider with this model is the accessibility differences between each mode. The Server mode can directly interact with server logic, whereas the WebAssembly mode requires API calls for communication. Consequently, you'll need to develop two distinct processes for each rendering mode to interact with server resources.

    The need for duplicated server access logic should be carefully weighed when considering the implementation of the InteractiveAuto rendering mode.

    Testing Challenges

    Testing this feature presents additional challenges. To effectively test the Blazor Server path, you will need to delete the WebAssembly package from the browser after each test.

    Due to this challenge, the demonstration of this rendering mode option has been omitted from this lab.

    However, if you are comfortable with your browser's developer tools, you are encouraged to experiment on your own. Simply declare the @rendermode InteractiveAuto directive and then manually remove the downloaded WebAssembly package using the developer tools.

    Congratulations

    Congratulations on finishing this lab.

    Hopefully this introduction to the different rendering modes has helped to provide you with a good idea of the benefits and trade-offs of using the various rendering modes within your application.

    The best as you continue your Blazor learning journey. Looking forward to seeing what you create.

About the author

Jeff Hopper is a polyglot solution developer with over 20 years of experience across several business domains. He has enjoyed many of those years focusing on the .Net stack.

Real skill practice before real-world application

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight