Blazor component: Razor tutorial and example

Published: Tuesday 7 March 2023

Razor components, also known as Blazor components are used for rendering a Blazor app.

This example will show what files are created when creating a Blazor WebAssembly app in Visual Studio using the default template.

In-addition, this tutorial will demonstrate how to create a component and how to set a parameter attribute within one.

Creating a Blazor WebAssembly app

When creating a Blazor WebAssembly application, a number of files with the .razor extension are created.

Razor pages in a Blazor WebAssembly app

Razor pages in a Blazor WebAssembly app

The filename represents the ID of the Razor component. For example, the Index.razor component has an ID of Index.

Program.cs file is also created. Inside that, it launches the Blazor WebAssembly app off the App component.

// Program.cs
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using RoundTheCode.BlazorComponent;
 
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app"); // Launches the Blazor WebAssembly app
builder.RootComponents.Add<HeadOutlet>("head::after");
 
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
 
await builder.Build().RunAsync();

Component files

The App component uses the routeData instance for routing. It also states the default layout to use, which is the MainLayout component.

<!-- App.razor -->
<Router AppAssembly="@typeof(App).Assembly">
	<Found Context="routeData">
		<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
		<FocusOnNavigate RouteData="@routeData" Selector="h1" />
	</Found>
	<NotFound>
		<PageTitle>Not found</PageTitle>
		<LayoutView Layout="@typeof(MainLayout)">
			<p role="alert">Sorry, there's nothing at this address.</p>
		</LayoutView>
	</NotFound>
</Router>

Inside the MainLayout component, it references a NavMenu component. This represents all the links in the navigation menu that appears on the left-hand side of the page.

<!-- MainLayout.razor -->
<div class="page">
	<div class="sidebar">
		<NavMenu />
	</div>

	...
</div>

The NavMenu component renders the links using the NavLink component. This link component is built-in to the Blazor framework, and it allows a link to be highlighted as active if it's routed to the same page that is being linked.

The NavLink component has a number of attributes that can be set. This is similar to the HTML a tag, and allows for the link to be set with the href attribute, as well as any class names.

<!-- NavMenu.razor -->
<div class="top-row ps-3 navbar navbar-dark">
	<div class="container-fluid">
		<a class="navbar-brand" href="">RoundTheCode.BlazorComponent</a>
		<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
			<span class="navbar-toggler-icon"></span>
		</button>
	</div>
</div>
 
<div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
	<nav class="flex-column">
		<div class="nav-item px-3">
			<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
				<span class="oi oi-home" aria-hidden="true"></span> Home
			</NavLink>
		</div>
		<div class="nav-item px-3">
			<NavLink class="nav-link" href="counter">
				<span class="oi oi-plus" aria-hidden="true"></span> Counter
			</NavLink>
		</div>
		<div class="nav-item px-3">
			<NavLink class="nav-link" href="fetchdata">
				<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
			</NavLink>
		</div>
	</nav>
</div>
 
@code {
	private bool collapseNavMenu = true;

	private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

	private void ToggleNavMenu()
	{
		collapseNavMenu = !collapseNavMenu;
	}
}

The MainLayout component also renders the Razor syntax @Body. This will route to a Razor component depending on the route data that is set.

<!-- MainLayout.razor -->
<div class="page">
	...
	<main>
		<div class="top-row px-4">
			<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
		</div>

		<article class="content px-4">
			@Body
		</article>
	</main>
</div>

For example, the home page will route to the Index component. It knows that because the Index component contains the @page directive which has it's parameter set to /.

<!-- Index.razor -->
@page "/"
 
<PageTitle>Index</PageTitle>
 
<h1>Hello, world!</h1>
 
Welcome to your new app.
 
<SurveyPrompt Title="How is Blazor working for you?" />

When loading the Blazor WebAssembly application, it renders the navigation links on the left-hand side and the content on the right-hand side.

Running the Blazor WebAssembly app

Running the Blazor WebAssembly app

Creating a Razor component

In Visual Studio, creating a Razor component is relatively simple. Right-click on a folder in the Solution Explorer, and go to Add and Razor Component...

Add a new Razor component in Visual Studio

Add a new Razor component in Visual Studio

Give it a name. In this instance, we want to create a component that represents the news. So, we'll name it News.razor.

Add a new Razor component to a Blazor WebAssembly app

Add a new Razor component to a Blazor WebAssembly app

That goes ahead and creates the Razor component. As we want to render this component to /news, we need to include the @page directive and set the parameter to /news.

<!-- News.razor -->
@page "/news"
<h3>News</h3>

Setting a parameter attribute

We now want to show the news headlines by referencing a separate Razor component. For this, we create a new shared Razor component, and call it NewsHeadlines.razor.

As this component is not going to be routed to a page, we don't need to include the @page directive.

To reference it in the News component, we simply add the ID of the component, separated with the < and >. As the file is called NewsHeadlines.razor, the ID of the component is NewsHeadlines.

<!-- News.razor -->
@page "/news"
<h3>News</h3>
<NewsHeadlines />

For the NewsHeadlines component, we want to set a title for it. As this component might be shared across multiple components, we want to set a different title depending on which component it's being referenced from.

To do that, we will set a Title property in the NewsHeadlines component, and mark it with the [Parameter] attribute.

Marking this property with a parameter attribute allows us to set the value of it when it's referenced from another component.

The final thing to do is to render the Title property to the NewsHeadlines component. This is done by calling @Title.

<!-- NewsHeadlines.razor -->
@Title
 
@code {
	[Parameter]
	public string Title { get; set; }
}

Now that the title has been set as a parameter, we can append the Title attribute when referencing the NewsHeadlines component.

<!-- News.razor -->
@page "/news"
<h3>News</h3>
<NewsHeadlines Title="My latest headlines" />

This also means that we can reference the NewsHeadlines component across multiple Razor components and change the title where necessary.

Watch the video

Watch our video where we show how Razor components work, how to create one, and how to set a parameter attribute. As a bonus, we'll demonstrate how to set a parameter from a querystring.

Learn more about Razor components

We have only scratched the surface when it comes to Razor components. With our building your first app in Blazor WebAssembly online course, we go into components in more detail and talk about parameters, as well as the @code block and other built-in components.

In-addition, our Blazor WebAssembly foundation skills online course looks more into configuration, API integration, logging and deployment.

Both of these courses are essential for building a Blazor WebAssembly app and understanding how the framework works.