mefechoel / svelte-navigator

Simple, accessible routing for Svelte
Other
504 stars 39 forks source link

Login component not rendered when navigating directly to a PrivateRoute in provided example #16

Closed mabentley85 closed 4 years ago

mabentley85 commented 4 years ago

Describe the bug When pointing my browser to http://localhost:6062/profile, the URL is properly redirected to http://localhost:6062/login but the login form component is not displayed.

To Reproduce Steps to reproduce the behavior:

  1. Clone the repo
  2. cd svelte-navigator/example/private-routes
  3. Run npm install and npm start
  4. Navigate to http://localhost:6062/profile in web browser
  5. The URL is properly redirected to http://localhost:6062/login, but the login form component is not rendered as shown in the screen shot. If you click the "Profile" link then the login form will be properly displayed.

Expected behavior When you land on a private route the login form should be displayed.

Screenshots Screen Shot 2020-09-08 at 12 09 56 PM

Desktop (please complete the following information):

mefechoel commented 4 years ago

This is probably what happened in #8. I can now reproduce the bug, thanks for the detailed description! I've had a look and I'm quite sure the bug originates in src/history.js, line 81. It seems as though history.replaceState is asynchronous and does not immediately update window.location.

As I see it, there are three possible ways this could be fixed. Either wait a short time before updating the internal location. This is probably fragile and not a great idea. Maybe there is a browser event that is fired when the state is replaced, but I've not seen this in other history implementations, but it should be investigated. Probably the best way to fix it now would be to manually parse the new path and create the next location from that.

mefechoel commented 4 years ago

Ok, I've identified the actual cause. history.replaceState is not asynchronous. The problem was, that the navigation to /login occures before the onMount function of Router is called. The Router subscribes to changes in the history on mount. However the first change gets lost, because it occures before the Router has a chance to subscribe to the history. To fix this, I had to change the behaviour of the history module. It now calles its subscribers (i.e. the Router) the moment they subscribe, and not only on changes, just like Svelte stores do.

mefechoel commented 4 years ago

Fixed in 3.1.1