Navigation in a Blazor application

The standard means of navigation within any web application is via the HTML anchor element, and Blazor applications are no different.

<a href="/">Home</a>

Blazor also provides two components designed to aid in navigation: the NavLink component and the NavigationManager component.

The NavLink component is a built-in component that generates anchor elements and toggles CSS classes on the anchor element that represents the page that the user is currently on. By default the value applied to the class attribute for the current page is active (although this is configurable via the ActiveClass parameter, see later). It is down to the developer to provide suitable styles for the active class if they want to change the appearance of the currently active navigation item.

The default project template includes an example of the NavLink component in use within the NavMenu component (located in the Shared folder). The following example replicates the default template, with the CSS classes and icon mark-up removed for clarity:

<ul>
    <li>
        <NavLink href="" Match="NavLinkMatch.All">
             Home
        </NavLink>
    </li>
    <li>
        <NavLink href="counter">
             Counter
        </NavLink>
    </li>
    <li>
        <NavLink href="fetchdata">
             Fetch data
        </NavLink>
    </li>
</ul>

The value passed to the href attribute of the NavLink component is the route template value applied to the @page directive in the target component. In the default template, the leading "/" is omitted from the href attribute, but you can include it if you prefer:

<NavLink href="/" Match="NavLinkMatch.All">
     Home
</NavLink>

The Match parameter of the NavLink component takes a NavLinkMatch enumeration that specifies how URLs should be matched to the value provided to the href attribute in order for the active class to be applied to the rendered anchor element. NavLinkMatch.All specifies that the whole of the URL should match the href value in order for the active class to be applied. NavlinkMatch.Prefix specifies that the active class should be applied when the href value matches the prefix of the URL.

In the following example, Prefix is specified as the matching behaviour for the first NavLink component, while the other two have All specified:

<li>
    <NavLink href="/orders"  Match="NavLinkMatch.Prefix">
        Orders
    </NavLink>
</li>
<li>
    <NavLink href="/orders/details"  Match="NavLinkMatch.All">
        Order Details
    </NavLink>
</li>
<li>
    <NavLink href="/orders/edit"  Match="NavLinkMatch.All">
            Edit Order
    </NavLink>
</li>

When the user navigates to /orders, only the first link becomes active. When the user navigates to /orders/details, the first links stays active, because it still matches the prefix of the URL, and the second link also becomes active because it matches the whole of the URL.

Route parameter values are considered for the purposes of matching URLs but query string values and fragments are ignored.

The ActiveClass Parameter

The ActiveClass parameter enables you to set the value of the CSS class (default active) that is applied to the currently active NavLink component. It takes a string. If you would like multiple CSS classes applied to the currently active link, you can specify those as you normally would:

<NavLink href="/orders" ActiveClass="current on">
    Orders
</NavLink>

Any other attributes specified on the NavLink component are automatically applied to the rendered anchor element. If you specify additional CSS classes to the NavLink component via a class attribute, the ActiveClass values are appended and removed separately:

<NavLink href="/orders" class="link" ActiveClass="current on">
    Orders
</NavLink>

The preceding example is rendered as follows when the link is not active:

<a href="/orders" class="link">Orders</a>

And like this when it is active:

<a href="/orders" class="link current on">Orders</a>

The NavigationManager Component

The NavigationManager component provides utility methods for working with URIs and performing navigation. It is registered as a service as part of the default set up of a Blazor application. It has the following members:

Member Description Examples (based on the URL scheme for this page)
Uri Gets the current absolute URI as a string. https://www.learnblazor.com/navigation
BaseUri Gets the base URI (with a trailing slash) that can be prepended to relative URI paths to produce an absolute URI as a string. https://www.learnblazor.com/
NavigateTo Navigates to the specified URI. Takes an optional boolean parameter forceLoad which is false by default. If true, the browser is forced to load the new page from the server, bypassing client-side routing.
LocationChanged Fires when the navigation location has changed.
ToAbsoluteUri Converts a relative URI into an absolute URI as a Uri datatype. e.g. NavigationManager.ToAbsoluteUri("navigation") results in "https://www.learnblazor.com/navigation"
ToBaseRelativePath Converts an absolute URI into a URI relative to the base URI prefix as a string. e.g NavigationManager.ToBaseRelativePath(NavigationManager.Uri) results in "routing".

The default WebAssembly implementation of the NavigationManager uses JavaScript to effect client-side navigation. The following example shows an instance of the NavigationManager being obtained from the service container and used to navigate the user to a different page based on the click of a button:

@page "/"
@inject NavigationManager navigationManager

<button @onlick="Navigate">Click</button>
@code{
    void Navigate()
    {
        navigationManager.NavigateTo("/other");
    }
}

Working With Query Strings

If you want to pass data such as component parameter values via a URL in a Blazor application, you will usually pass it as URL segments that match route parameters. Sometimes, you might need to work with data in query strings, for example if you have to cater for legacy URLs for SEO purposes.

From .NET 6, components can receive parameter values directly from the query string if you apply the SupplyParameterFromQuery attribute to the parameter declaration:

[Parameter] 
[SupplyParameterFromQuery]
public string Name { get; set; }

This works for the following types, nullable variants of them where applicable and arrays of them, nullable or not:

  • string
  • bool
  • DateTime
  • decimal
  • double
  • float
  • Guid
  • int
  • long

The Microsoft.AspNetCore.WebUtilities package contains some helper methods that enable you to generate query strings and, if you need to obtain parameter values prior to .NET 6., parse them. First, you need to install the package into your application:

PM> install-package Microsoft.AspNetCore.WebUtilities

The WebUtilities package contains a QueryHelpers class, which offers a couple of useful static methods: AddQueryString and ParseQuery.

Generating a Query String

The AddQueryString method takes a Dictionary<string,string> to represent the name/value pairs that should appear in the query string. It will ensure that the result is encoded correctly.

var query = new Dictionary<string, string> { { "name", "value" } };
var uriWithQuery = QueryHelpers.AddQueryString(navigationManager.Uri, query);

Parsing Query String Values

The ParseQuery method returns a StringValues type, which represents "zero/null, one, or many strings in an efficient way". Hence you can use LINQ operators to access values.

var uri = navManager.ToAbsoluteUri(navigationManager.Uri);
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("name", out var param))
{
    name = param.First();
}
Last updated: 15/02/2023 09:03:07

Latest Updates

© 2023 - 2024 - Mike Brind.
All rights reserved.
Contact me at Outlook.com