You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the current version, the state read using $page.state (or the newer $app/state version) can easily get out of sync with the actual history.state, two very common methods are:
This can have certain consequences depending on how you use shallow state. I use it for drawers/modals, and this un-sync thing causes many issues, such as the back button not working after a refresh (history.state is popped but nothing happens as $page.state is already empty). Then, clicking the forward button makes the popup magically appear, as SvelteKit finally uses the browser state.
This feels like a bug, which is why so many issues have been opened on this topic, at least 3-4 other than the 2 mentioned above, such as #13139, which actually prompted me to write this issue to group everything together.
Describe the proposed solution
I understand the initial thoughts behind the choice to make the state reset on refresh - to avoid flashes during hydration. However, improving SSR at the cost of breaking CSR is not the correct choice IMO.
The primary use-cases of shallow routing are:
With URL change - this allows for example, as Rich Harris stated, to implement preview navigation. The user clicks on an image, and a dialog/similar viewer appears in the current page, and /image/12345 is appended to the URL using shallow routing. Upon refreshing the page, the new URL is requested from the server, which opens up a new full page viewer. This is also the page that is opened, for example, when sharing the URL or arriving from a search engine.
Without URL change - this cannot be used with SSR as the local state is never available on the server, unlike the URL change. This can be used, for example, to control dialogs and drawers, this avoid the very common annoyance when you try to use the back button on a mobile browser, and instead of closing the current modal, the page is exited altogether.
The question is: to delete or not delete the state on page refresh? For case 1, it should be deleted, as an entire new page is loaded, which does not use this state. For case 2, it depends - do we want the dialog/drawer to re-open after a refresh? Sometimes the answer is yes, but this depends on the app.
Currently, the state is always deleted, although in this buggy manner where it's actually still there causing the back button to not work, or causing it to reappear after going back/forward. There are a few changes that can be done:
correctly delete the state from history.state, however this is very tricky or even impossible to do. This would fix the issues associated with use-case 2 described above.
allow the user to decide if the state should be restored in hydration (feature/minor change)
change the default behaviour depending on whether the URL is changed, or if SSR is disabled for the page (breaking change for v3)
Finally, there's the issue of page state being deleted on form submissions, but I believe this is the exact same issue as above. Consider a form without use:enhance. If the state is deleted on page refresh, this is identical to the state being deleted on submission in an enhanced form. This is why the behaviour of form submissions should be the same as for a page refresh by default, but still configurable, as it's not a full-page reload after all.
Workaround
You can find a workaround that keeps the page state in sync by loading it from history.state on page load here.
Importance
would make my life easier
The text was updated successfully, but these errors were encountered:
Describe the problem
In the current version, the state read using
$page.state
(or the newer$app/state
version) can easily get out of sync with the actualhistory.state
, two very common methods are:$page.state
is cleared wheninvalidate
is invoked #11783$page.state
is lost after page refresh #11956This can have certain consequences depending on how you use shallow state. I use it for drawers/modals, and this un-sync thing causes many issues, such as the back button not working after a refresh (
history.state
is popped but nothing happens as$page.state
is already empty). Then, clicking the forward button makes the popup magically appear, as SvelteKit finally uses the browser state.This feels like a bug, which is why so many issues have been opened on this topic, at least 3-4 other than the 2 mentioned above, such as #13139, which actually prompted me to write this issue to group everything together.
Describe the proposed solution
I understand the initial thoughts behind the choice to make the state reset on refresh - to avoid flashes during hydration. However, improving SSR at the cost of breaking CSR is not the correct choice IMO.
The primary use-cases of shallow routing are:
/image/12345
is appended to the URL using shallow routing. Upon refreshing the page, the new URL is requested from the server, which opens up a new full page viewer. This is also the page that is opened, for example, when sharing the URL or arriving from a search engine.The question is: to delete or not delete the state on page refresh? For case 1, it should be deleted, as an entire new page is loaded, which does not use this state. For case 2, it depends - do we want the dialog/drawer to re-open after a refresh? Sometimes the answer is yes, but this depends on the app.
Currently, the state is always deleted, although in this buggy manner where it's actually still there causing the back button to not work, or causing it to reappear after going back/forward. There are a few changes that can be done:
history.state
, however this is very tricky or even impossible to do. This would fix the issues associated with use-case 2 described above.Finally, there's the issue of page state being deleted on form submissions, but I believe this is the exact same issue as above. Consider a form without
use:enhance
. If the state is deleted on page refresh, this is identical to the state being deleted on submission in an enhanced form. This is why the behaviour of form submissions should be the same as for a page refresh by default, but still configurable, as it's not a full-page reload after all.Workaround
You can find a workaround that keeps the page state in sync by loading it from
history.state
on page load here.Importance
would make my life easier
The text was updated successfully, but these errors were encountered: