-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Overview and Motivation
In Blazor applications, navigation links using NavLink with Match=NavLinkMatch.All don't appear selected when query strings or fragments are appended to the URL. Users reported this as confusing when navigating in applications with query parameters.
The issue occurs because the current implementation performs exact matching including query strings and fragments. After discussion, it was determined that the original intention of NavLinkMatch.All was to match the path portion only, ignoring queries and fragments. This proposal adds a virtual method to allow customization of this behavior.
Proposed API
namespace Microsoft.AspNetCore.Components.Routing
{
public partial class NavLink : IComponent, IDisposable
{
protected virtual bool ShouldMatch(string currentUriAbsolute)
{
}
}
}Usage Examples
Developers can override the ShouldMatch method to implement custom matching behavior:
public class CustomNavLink : NavLink
{
protected override bool ShouldMatch(string currentUriAbsolute)
{
bool baseMatch = base.ShouldMatch(currentUriAbsolute);
if (!baseMatch || string.IsNullOrEmpty(hrefAbsolute) || Match != NavLinkMatch.All)
{
return baseMatch;
}
if (NormalizeUri(hrefAbsolute) == NormalizeUri(currentUriAbsolute))
{
return true;
}
return false;
}
}Alternative Designs
- Adding a property to control query string matching behavior was considered in issue fix NavLink with query string can't be selected correctly #32168, but this approach would not handle fragments or other URL elements consistently.
- A specialized version of NavLink (e.g., NavLinkIgnoreQuery) was considered, but the virtual method approach provides more flexibility for developers to create custom implementations.
Risk Considerations
This behavior change might break existing applications that rely on the current exact matching behavior, including query strings. Links may start or stop highlighting differently after upgrading.
To mitigate this risk, the old behavior can be preserved by setting the following app context switch:
Microsoft.AspNetCore.Components.Routing.NavLink.EnableMatchAllForQueryStringAndFragment