
One little niggle about Blazor (well, there’s maybe more than one 😉) is that I have to hard code text to specify the page routes in routable components using ‘page’. I can’t just use a variable or constant defined somewhere else, it has to be a hard coded string!
For example, the classic ‘counter’ component that comes with a sample Blazor client project, we have ‘@page “/counter”‘ as shown below:-
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
This is all well and good, but then the real issue is when we have to repeat the same on our navmenu for example (see the link with ‘href=”counter’ bit). So already we’ve got 2 hard coded strings:-
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">BlazorApp5</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="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
</NavLink>
</div>
</nav>
</div>
@code {
private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}

What happens if you’ve got several links to a page? This is starting to drive me nuts, we’ve got all that repeating hard coded text all over the place. If you wanted to change the link route you’ve got to find all these references and replace them one by one. Surely there is a better way? Yes there is, say hello to the ‘Route’ attribute! With this, the Razor ‘page’ directive can simply be replaced like so:-
@page "route goes here"
@attribute [Route("route goes here")]

So what? Why use ‘Route’? Well, the main reason is that now you can use constants to specify values for the attribute. Quite often I’ll create a small static class with my routes then use that to control my page routing:-
public static class MyRoutes
{
public const string SomeRoute = "/some/route";
}
Then in my components I can just use this instead of ‘page’:-
@attribute [Route(MyRoutes.SomeRoute)]
Then in the navmenu or other links I just use that class again:-
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">BlazorApp5</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="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="@MyRoutes.SomeRoute">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
</NavLink>
</div>
</nav>
</div>
@code {
private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
Sorted… To be honest, since I discovered this I now only use the ‘Route’ attribute so that I don’t have to hard code strings for routes. I use a similar technique for API routes too, so now I’ve no hard coded string routes anywhere 😎
Well, that’s it for this one, hope it comes in useful for someone…