Skip to content

Commit 3e9b848

Browse files
authored
Force full reload on popstate (#54877)
1 parent ad9e004 commit 3e9b848

File tree

8 files changed

+100
-5
lines changed

8 files changed

+100
-5
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/src/Services/NavigationManager.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,9 @@ async function onBrowserInitiatedPopState(state: PopStateEvent) {
248248
await navigateHistoryWithoutPopStateCallback(delta);
249249
}
250250

251-
await notifyLocationChanged(false);
251+
// We don't know if popstate was triggered for a navigation that can be handled by the client-side router,
252+
// so we treat it as a intercepted link to be safe.
253+
await notifyLocationChanged(/* interceptedLink */ true);
252254
}
253255

254256
async function notifyLocationChanged(interceptedLink: boolean, internalDestinationHref?: string) {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using Components.TestServer.RazorComponents;
2+
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
3+
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
4+
using Microsoft.AspNetCore.E2ETesting;
5+
using OpenQA.Selenium;
6+
using TestServer;
7+
using Xunit.Abstractions;
8+
9+
namespace Microsoft.AspNetCore.Components.E2ETests.Tests;
10+
11+
public class GlobalInteractivityTest(
12+
BrowserFixture browserFixture,
13+
BasicTestAppServerSiteFixture<RazorComponentEndpointsStartup<GlobalInteractivityApp>> serverFixture,
14+
ITestOutputHelper output)
15+
: ServerTestBase<BasicTestAppServerSiteFixture<RazorComponentEndpointsStartup<GlobalInteractivityApp>>>(browserFixture, serverFixture, output)
16+
{
17+
[Fact]
18+
public void CanFindStaticallyRenderedPageAfterClickingBrowserBackButtonOnDynamicallyRenderedPage()
19+
{
20+
Navigate("/subdir/static");
21+
22+
Browser.Click(By.CssSelector("a[href=dynamic]"));
23+
Browser.Navigate().Back();
24+
25+
var heading = Browser.Exists(By.TagName("h1"));
26+
Browser.Equal("Statically Rendered", () => heading.Text);
27+
}
28+
}

src/Components/test/testassets/Components.TestServer/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ public static async Task Main(string[] args)
3434
["Blazor web with server-side blazor root component"] = (BuildWebHost<RazorComponentEndpointsStartup<Root>>(CreateAdditionalArgs(args)), "/subdir"),
3535
["Hosted client-side blazor"] = (BuildWebHost<ClientStartup>(CreateAdditionalArgs(args)), "/subdir"),
3636
["Hot Reload"] = (BuildWebHost<HotReloadStartup>(CreateAdditionalArgs(args)), "/subdir"),
37-
["Dev server client-side blazor"] = CreateDevServerHost(CreateAdditionalArgs(args))
37+
["Dev server client-side blazor"] = CreateDevServerHost(CreateAdditionalArgs(args)),
38+
["Global Interactivity"] = (BuildWebHost<RazorComponentEndpointsStartup<GlobalInteractivityApp>>(CreateAdditionalArgs(args)), "/subdir"),
3839
};
3940

4041
var mainHost = BuildWebHost(args);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8" />
6+
<base href="/subdir/" />
7+
8+
<HeadOutlet />
9+
</head>
10+
11+
<body>
12+
<Components.WasmMinimal.Routes @rendermode="@RenderModeForPage" />
13+
<script src="_framework/blazor.web.js" autostart="false"></script>
14+
<script>
15+
Blazor.start({
16+
webAssembly: {
17+
loadBootResource: (type, name, defaultUri, integrity) => `WasmMinimal/_framework/${name}`
18+
}
19+
});
20+
</script>
21+
</body>
22+
23+
</html>
24+
25+
26+
@code {
27+
[CascadingParameter]
28+
private HttpContext HttpContext { get; set; } = default!;
29+
30+
// Statically render pages in the "/Account" subdirectory like we do in the Blazor Web template with Individaul auth.
31+
private IComponentRenderMode? RenderModeForPage => HttpContext.Request.Path.StartsWithSegments("/static")
32+
? null
33+
: RenderMode.InteractiveAuto;
34+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@page "/static"
2+
3+
@* This should be statically rendered by GlobalInteractivityApp. *@
4+
<h1>Statically Rendered</h1>
5+
6+
<ul>
7+
<li><NavLink href="dynamic">Dynamic page</NavLink></li>
8+
</ul>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@using Microsoft.AspNetCore.Components.Routing
2+
@using Microsoft.AspNetCore.Components.Web
3+
4+
@rendermode RenderMode.InteractiveWebAssembly
5+
6+
@page "/dynamic"
7+
8+
<h1>Dynamically Rendered</h1>
9+
10+
<ul>
11+
<li><NavLink href="static">Static page</NavLink></li>
12+
<li><NavLink href="persist-wasm-state">Another dynamic page</NavLink></li>
13+
</ul>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@using Microsoft.AspNetCore.Components.Routing
2+
3+
<Router AppAssembly="@typeof(Program).Assembly">
4+
<Found Context="routeData">
5+
<RouteView RouteData="@routeData" />
6+
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
7+
</Found>
8+
<NotFound>There's nothing here</NotFound>
9+
</Router>

0 commit comments

Comments
 (0)