In this article, we learn nine best practices for building Blazor web applications. Those best practices are built on real-world experience working with Blazor for a few years.
The first and, from my experience, the most important step when learning Blazor is properly understanding the component lifecycle.
Blazor uses a component-oriented rendering system similar to other modern web application frameworks such as Angular or React.
Learn about Creating a Blazor Component in another earlier article of the Blazor Basics series.
Besides learning how to implement Blazor components, it’s important to understand when a Blazor component automatically re-renders and how to control that behavior.
For example, we can override the ShouldRender
lifecycle method to manage UI refreshing. If the method returns true, the component is re-rendered.
One of the biggest challenges in component-oriented user interface development is deciding when to break your code into multiple components.
What works for me is that I start simple. I first create a routable page component and write all the code directly inside this component.
At some point, the code grows, and I realize that part of the code does not have to do with the other part. For example, form handling has nothing to do with rendering a table full of information. At that point, I decide to split the components, extract child components and turn the page component into an orchestrator of multiple child components.
There is no right or wrong when splitting components, and it requires experience to get a feeling for what works best. However, one of the guidelines that works well for me is that I extract what belongs together and value cohesion more than size (the number of lines of code).
With the introduction of render modes in .NET 8, we get a lot more flexibility for Blazor applications compared to previous versions.
For example, we can implement an entirely server-rendered web application without any interactivity. Or we can mix and match Blazor Server and Blazor WebAssembly interactivity in a single application.
To allow for a flexible architecture, I highly recommend setting Blazor components to render mode agnostic.
What does that mean? It means that we want to avoid setting the interactivity type inside a lower-level component. Instead, we want to set the render mode when using the component inside a higher-level component.
This allows a component to be used as part of a Blazor Server and Blazor WebAssembly interactivity application.
Learn how to bind C# methods to events triggered by HTML elements. It’s the fundamental mechanism to implement onClick handlers for buttons or submit handlers for HTML forms.
When registering to .NET events, such as the LocationChanged
event of the NavigationManager
class, make sure to always unsubscribe from the event when the component is disposed. Otherwise, the component will not be destroyed by the garbage collector.
@implements IDisposable
@inject NavigationManager NavigationManager
protected override void OnInitialized()
{
NavigationManager.LocationChanged += LocationChanged;
}
void LocationChanged(object sender, LocationChangedEventArgs e)
{
System.WriteLine("Location changed");
}
void IDisposable.Dispose()
{
NavigationManager.LocationChanged -= LocationChanged;
}
When it comes to communication between components, Event Callbacks are the standard way to call a callback on the parent component from a child component.
Choose appropriate state management techniques based on the application’s complexity.
Blazor offers different options for state management. Component parameters are the simplest, followed by cascading values and extracting the state into dedicated service implementations.
For large applications, a state management library like Fluxor or another global state container could be an option. However, be aware of the challenges that global state handling brings to your application.
Use a clean, clear and organized code structure. For example, group related components within folders and place services and pages into logical folders.
Also, follow the best practices for naming components, such as naming conventions and separate concerns by extracting components to improve the maintainability of the entire application.
The new single Blazor Web Application template in .NET 8 contains a good starting point. However, make sure to reorganize your code when your application significantly grows in one area or the other. You don’t want to be constantly searching for related pieces of your code.
Educate yourself about web security best practices, such as the OSWASP Top 10, and implement measures, especially when dealing with sensitive data.
Use ASP.NET Core authentication and authorization to protect access to your endpoints and Blazor pages. Only store information that is required to perform your business actions. Always use HTTPS.
Don’t store user passwords yourself. Use an authentication service provider instead. If there is no other option and you have to store individual user accounts yourself, make sure to properly hash the passwords using a strong hashing algorithm, such as BCrypt.
Implement a robust error-handling solution to handle exceptions. Make sure your logs contain relevant information to solve issues in your code.
At the same time, avoid logging sensitive information and replace it with placeholders.
You can utilize the ASP.NET Core logging framework or add a more flexible and capable solution, such as Serilog.
One of the most underrated tips when it comes to software development in general, but also when it comes to Blazor development, is keeping it simple.
There are so many complex implementations that simple solutions could replace. I always strive to implement the simplest possible solution to any given problem.
For example, when I need to pass a value to a component, I start by using a component parameter. Why implement a complex service and inject it into the child component when you can solve the problem with a simple component parameter?
Applying the nine best practices mentioned in this article will help you write maintainable and extensible Blazor web applications.
If you want to learn more about Blazor development, you can watch my free Blazor Crash Course on YouTube. And stay tuned to the Telerik blog for more Blazor Basics.
Claudio Bernasconi is a passionate software engineer and content creator writing articles and running a .NET developer YouTube channel. He has more than 10 years of experience as a .NET developer and loves sharing his knowledge about Blazor and other .NET topics with the community.