See how to (re)use Razor components in Blazor web applications from Razor class libraries.
Blazor is a modern, component-oriented web development framework for the .NET platform. It provides C# and .NET developers access to modern web development with the option to write (most of) the interaction code in C# instead of JavaScript.
One of the most significant advantages of using a component-oriented web framework is the simplicity of sharing components between web applications. Reusable component libraries help promote consistency and reduce development time across multiple projects or teams.
In this article, I will show you how to share components using a Razor class library project and share best practices for versioning, documenting and maintaining it.
There are different reasons for introducing a shared Razor class library in your Blazor web application projects.
For example, you want to share styles across different applications to make all of your internal applications look and feel the same.
Or you want to share components, such as having the same login page for all your applications.
In all those use cases, you create a Razor class library and share the components and styles by placing them inside the class library project. You then add a project reference from the Blazor application project to the shared Razor class library.
You will be able to reference Razor components from the application project when you add a project reference to the shared library.
However, when sharing CSS or JavaScript, we need to wire them up with the application.
Components that use CSS Isolation are automatically handled by the Blazor web framework; however, for standalone *.css
files, you need to add a link element in the head section of the Blazor application (usually the App.razor
file) referencing the .css
file:
<link href="@Assets["_content/ComponentLibrary/additionalStyles.css"]" rel="stylesheet">
Use the correct project name and filename to reference the standalone *.css
file.
For Standable Blazor WebAssembly projects, the CSS reference has a different structure:
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
To reuse routable (page) components, you need to provide a reference to the shared project assembly in the AdditionalAssemblies
parameter of the Router
definition inside the Routes.razor
file.
AdditionalAssemblies="new[] { typeof(ComponentLibrary.Component1).Assembly }"
Images and JavaScript files stored in the public wwwroot
folder of the shared application can be referenced using the same naming pattern as used for CSS files.
<img alt="Profile Picture" src="_content/ComponentLibrary/profile.png" />
This code references a profile.png
file from the wwwroot
folder of the ComponentLibrary
shared Razor class library project.
You can share service implementations, assets, utility code, etc., besides Blazor components in the shared Razor class library. Technically, you do not need multiple projects, even though that’s possible if you have a reason for splitting up the different resources.
Although using direct project references works for smaller projects, you might soon hit some of its limitations. For example, when you change the components, it directly affects all applications.
Suppose you have multiple applications depending on the shared components. In that case, consider using versioning for your shared library and allowing consumers to upgrade their applications to the latest version gradually.
In that case, publishing a NuGet package to NuGet.org or a private feed is better than directly referencing the shared components library from your Blazor web applications.
You want to add the package metadata to the .csproj
file of the shared Razor class library.
Next, you use the dotnet pack
command in your CI/CD setup to generate the NuGet package. You can then publish the generated package to your NuGet feed.
Implementing shared components render mode agnostic is the best approach.
It means that you do not specify the render mode inside the implementation of the component in the shared Razor class library project.
Instead, you set or inherit the render mode when using the component in the application project.
There are two ways to specify the render mode for a component instance:
// Option 1: Using the rendermode attribute
<HeadOutlet @rendermode="InteractiveServer" />
// Option 2: Using the @rendermode directive
@rendermode InteractiveServer
This way, you (re)use the same component in Blazor Server and Blazor WebAssembly projects.
If you have multiple consumers for your shared component library, you might want to use Semantic Versioning (major, minor, patch) to help with migration and backward compatibility.
When multiple teams or different developers will work with the shared component library, write good documentation. You can utilize XML comments or tooling such as DocFX.
Explain what the component does and what limitations it might have. For example, state that the register component validates password strength using a specific service.
You can also implement a sample application that uses the components from the shared library to demonstrate its usage and to notice when you accidentally introduce a breaking change when changing the components.
Use a proper CI/CD setup to publish new versions of the shared components library.
Extracting Blazor components, CSS or JavaScript code into a Razor class library allows you to share the artifacts with multiple Blazor web applications.
For simple scenarios, direct project references are enough. However, when multiple or larger applications depend on your shared components library, you will benefit from publishing a NuGet package allowing you to version your components library.
You can publish your package publicly (using NuGet.org) or to a private feed, such as Azure Artifacts.
The biggest benefits of sharing components between applications are:
Familiarize yourself with Razor class libraries to introduce a maintainable, efficient architecture to your Blazor projects.
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.