();
+ app.FindElement(By.LinkText("Override layout with query, no trailing slash")).Click();
+ Browser.Equal("This is the page with overridden layout.", () => app.FindElement(By.Id("test-info")).Text);
+ AssertHighlightedLinks("Override layout with query, no trailing slash");
+ }
+
[Fact]
public void CanGoBackFromNotAComponent()
{
diff --git a/src/Components/test/testassets/BasicTestApp/RouterTest/LayoutOverridden.razor b/src/Components/test/testassets/BasicTestApp/RouterTest/LayoutOverridden.razor
new file mode 100644
index 000000000000..47d9c16d1c7a
--- /dev/null
+++ b/src/Components/test/testassets/BasicTestApp/RouterTest/LayoutOverridden.razor
@@ -0,0 +1,4 @@
+@page "/layout-overridden"
+@page "/layout-overridden/for-hash"
+@layout RouterTestLayoutNavLinksOverridden
+This is the page with overridden layout.
\ No newline at end of file
diff --git a/src/Components/test/testassets/BasicTestApp/RouterTest/LinksOverridden.razor b/src/Components/test/testassets/BasicTestApp/RouterTest/LinksOverridden.razor
new file mode 100644
index 000000000000..447d90c8b9f3
--- /dev/null
+++ b/src/Components/test/testassets/BasicTestApp/RouterTest/LinksOverridden.razor
@@ -0,0 +1,18 @@
+@using Microsoft.AspNetCore.Components.Routing
+
+
+ - Override layout (matches all)
+ - Override layout, no trailing slash (matches all)
+ - Override layout with query
+ - Override layout with query, no trailing slash
+ - Override layout with hash
+ - Override layout with hash, no trailing slash
+ - Override layout with extension
+ - Override Other
+ - Override Other with base-relative URL (matches all)
+
\ No newline at end of file
diff --git a/src/Components/test/testassets/BasicTestApp/RouterTest/NavLinkNotIgnoreQueryOrFragmentString.cs b/src/Components/test/testassets/BasicTestApp/RouterTest/NavLinkNotIgnoreQueryOrFragmentString.cs
new file mode 100644
index 000000000000..e384e24b23e7
--- /dev/null
+++ b/src/Components/test/testassets/BasicTestApp/RouterTest/NavLinkNotIgnoreQueryOrFragmentString.cs
@@ -0,0 +1,45 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Globalization;
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Routing;
+
+public class NavLinkNotIgnoreQueryOrFragmentString : NavLink
+{
+ string hrefAbsolute;
+ NavigationManager _navigationManager;
+
+ public NavLinkNotIgnoreQueryOrFragmentString(NavigationManager navigationManager)
+ {
+ _navigationManager = navigationManager;
+ }
+
+ protected override void OnInitialized()
+ {
+ string href = "";
+ if (AdditionalAttributes != null && AdditionalAttributes.TryGetValue("href", out var obj))
+ {
+ href = Convert.ToString(obj, CultureInfo.InvariantCulture) ?? "";
+ }
+ hrefAbsolute = _navigationManager.ToAbsoluteUri(href).AbsoluteUri;
+ base.OnInitialized();
+ }
+ 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;
+ }
+
+ private static string NormalizeUri(string uri) =>
+ uri.EndsWith('/') ? uri.TrimEnd('/') : uri;
+}
diff --git a/src/Components/test/testassets/BasicTestApp/RouterTestLayoutNavLinksOverridden.razor b/src/Components/test/testassets/BasicTestApp/RouterTestLayoutNavLinksOverridden.razor
new file mode 100644
index 000000000000..ff0c57ec65a9
--- /dev/null
+++ b/src/Components/test/testassets/BasicTestApp/RouterTestLayoutNavLinksOverridden.razor
@@ -0,0 +1,6 @@
+@using Microsoft.AspNetCore.Components
+@inherits LayoutComponentBase
+
+@Body
+
+
\ No newline at end of file