Navigation and NavigationManager
NavigationManager is a service Blazor registers in dependency injection that any component can inject with @inject NavigationManager Nav. It exposes the current Uri and BaseUri as properties, and a NavigateTo(string uri, ...) method to move the app to a new route programmatically, without requiring the user to click a link.
Cricket analogy: Like a team's designated runner who always knows the exact position of every fielder on the ground, NavigationManager is injected into a component and always knows the app's current Uri and BaseUri so code can act on it.
Programmatic Navigation with NavigateTo
NavigateTo(url, forceLoad, replace) takes two optional booleans beyond the target URL: forceLoad bypasses Blazor's client-side router entirely and performs a full browser reload of the destination, which is necessary when navigating to a non-Blazor endpoint or forcing fresh server-rendered state; replace swaps the current entry in the browser history stack instead of pushing a new one, so the back button skips over it.
Cricket analogy: Like calling for a full DRS review that resets the umpire's original call entirely, NavigateTo(url, forceLoad: true) discards the current Blazor app state and forces a full browser reload of the new page.
NavigationManager also provides ToAbsoluteUri and ToBaseRelativePath helper methods for converting between the app's relative route strings and fully qualified absolute URIs, which is essential when building shareable links or comparing the current Uri against a known relative path without hardcoding the app's host and base path.
Cricket analogy: Like knowing whether a fielder's position is described relative to the pitch or as absolute GPS coordinates on the ground, ToBaseRelativePath converts an absolute Uri into a path relative to the app's base, while ToAbsoluteUri does the reverse.
Reacting to Location Changes
Subscribing to NavigationManager.LocationChanged lets a component react whenever the URL changes, whether triggered by NavigateTo or the browser's own back/forward buttons; the LocationChangedEventArgs supplies the new Location and whether the change came from history navigation via IsNavigationIntercepted. Because this is a standard .NET event subscription, a component that implements IDisposable must unsubscribe in its Dispose method to avoid a memory leak.
Cricket analogy: Like a scorer who must stop logging deliveries the moment the innings ends or risk recording the wrong match, a component must unsubscribe from NavigationManager.LocationChanged in Dispose to avoid reacting to navigation after it's gone.
@implements IDisposable
@inject NavigationManager Nav
<button class="btn" @onclick="GoToDashboard">Go to Dashboard</button>
<p>Current path: @currentPath</p>
@code {
private string currentPath = string.Empty;
protected override void OnInitialized()
{
currentPath = Nav.ToBaseRelativePath(Nav.Uri);
Nav.LocationChanged += OnLocationChanged;
}
private void GoToDashboard()
{
Nav.NavigateTo("/dashboard", replace: true);
}
private void OnLocationChanged(object? sender, LocationChangedEventArgs e)
{
currentPath = Nav.ToBaseRelativePath(e.Location);
InvokeAsync(StateHasChanged);
}
public void Dispose()
{
Nav.LocationChanged -= OnLocationChanged;
}
}LocationChanged only fires reliably once a component is running in an interactive render mode. During static server-side prerendering (the default for many Blazor Web App pages before interactivity attaches), the event handler you subscribe to in OnInitialized may not receive updates until the component becomes interactive, so don't assume LocationChanged fires during the initial static render pass.
NavLink and Active Class Matching
The built-in NavLink component renders an anchor tag and automatically applies the active CSS class when its href matches the current URL, driven internally by the same NavigationManager. The Match parameter controls how strictly that comparison works: NavLinkMatch.All requires an exact match to the full current Uri, while the default NavLinkMatch.Prefix marks the link active whenever the current Uri starts with the link's href, which is what makes a parent navigation item stay highlighted while browsing any of its child routes.
Cricket analogy: Like distinguishing a fielder positioned exactly at the boundary rope from one anywhere in the outfield, NavLinkMatch.All only marks a NavLink active on an exact Uri match, while Prefix marks it active for any matching sub-route.
Calling NavigateTo from inside OnInitialized or OnInitializedAsync to redirect users (for example, an auth guard) is a legitimate pattern, but doing so without an early return or a guard condition can trigger a re-entrant render loop, since the redirect itself re-initializes the component pipeline. Always return immediately after calling NavigateTo in a lifecycle method.
- NavigationManager is an injectable service exposing the current Uri, BaseUri, and a NavigateTo method for programmatic navigation.
- NavigateTo's forceLoad parameter triggers a full browser reload; its replace parameter avoids adding a new browser history entry.
- ToAbsoluteUri and ToBaseRelativePath convert between relative route strings and fully qualified absolute URIs.
- LocationChanged is a standard .NET event that fires on navigation; components must unsubscribe in Dispose to avoid leaks.
- NavLink renders an anchor and automatically applies an active CSS class based on the current Uri.
- NavLinkMatch.Prefix (the default) keeps a link active for any nested matching route, while NavLinkMatch.All requires an exact match.
- Redirecting inside a lifecycle method like OnInitializedAsync requires care to avoid re-entrant navigation loops.
Practice what you learned
1. What does NavigateTo(url, forceLoad: true) do differently from a plain NavigateTo(url)?
2. Why must a component unsubscribe from NavigationManager.LocationChanged in Dispose?
3. What is the default Match mode for the NavLink component?
4. What does the replace parameter on NavigateTo control?
5. What information does LocationChangedEventArgs provide?
Was this page helpful?
You May Also Like
Routing with @page
Learn how Blazor's @page directive maps components to URLs, using route parameters and constraints to build navigable pages.
Authentication and AuthorizeView
Learn how Blazor's AuthenticationStateProvider, AuthorizeView, and the [Authorize] attribute work together to build authentication-aware UI.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics