Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avalonia in browser unexpectedly calls history.pushState #13999

Open
koustubhmoharir opened this issue Dec 20, 2023 · 2 comments
Open

Avalonia in browser unexpectedly calls history.pushState #13999

koustubhmoharir opened this issue Dec 20, 2023 · 2 comments
Labels
bug help-wanted A contribution from the community would be most welcome. os-browser

Comments

@koustubhmoharir
Copy link

Describe the bug

I am using Avalonia to render a few routes within a larger single page web application that has other routes rendered with React. Route switching happens with history.pushState.
During initialization of Avalonia, a call to the AvaloniaView constructor results in a call to history.pushState with window.location.href. This results in duplicating the entry in the browser's history stack. Based on WICG/interventions#21, it seems that the browser does not like this, because a lot of websites are abusing the history functionality to prevent users from going back. Subsequently, after some further navigation, if the back button is pressed, the browser fires a series of popstate events (instead of just one) and the application ends up getting unloaded entirely. Looking at the source code, the stack where the initial duplication happens is

AvaloniaView ctor
BrowserTopLevelImpl ctor
BrowserSystemNavigationManagerImpl ctor
NavigationHelper.AddBackHandler

To Reproduce

Steps to reproduce the behavior partially (just the part where the browser stack gets a duplicate entry):

  1. Create a fresh Avalonia browser application from the VS cross platform template.
  2. Change the target to .NET 8 and the Avalonia version to 11.0.6
  3. Open the application in the browser and right click the back button to view the history stack. Before Avalonia is initialized, the history is as expected.
  4. After the page finishes loading, there is a duplicate entry.

Expected behavior

Avalonia should not touch the browser history, or at least there should be a way to disable this.

Environment

  • OS: Browser
  • Avalonia-Version: 11.0.6

Additional context

I have tested this in Chrome and Firefox. Both browsers seem to implement an intervention where clicking the back button after a duplicate entry skips multiple pages instead of one.

@Gillibald
Copy link
Contributor

history.pushState(null, "", window.location.href);

Reading the current history before pushing a new state to ensure no duplicates should be possible. A PR is welcome here.

@timunie timunie added the help-wanted A contribution from the community would be most welcome. label Dec 21, 2023
@koustubhmoharir
Copy link
Author

This code supports the BackRequested event. But within a browser single page application, it seems to me that the only way to exercise control over what happens when Back / Forward is clicked is to use pushState appropriately. For example, if the intent is to dismiss a "dialog" when the Back button is clicked, pushState must be called when the dialog is shown. Then, in response to the popstate event, the application can either dismiss the dialog, or if there are some unsaved changes, call pushState again and update the dialog UI to prompt the user to explicitly cancel. But if the application has not taken care to do so, the framework cannot help.

Also, if the application has never called pushState, clicking on the back button will take the user out of the application entirely, and the best the application can do is to listen for the beforeunload event.

In other words, I don't think there is a way to provide the BackRequested API in a browser framework. The current Avalonia implementation was a workaround and browser interventions have now prevented that too.

I would love to know if my assessment is wrong and there is actually a way to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug help-wanted A contribution from the community would be most welcome. os-browser
Projects
None yet
Development

No branches or pull requests

4 participants