Fix preserve state and page store in Svelte adapter #522
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #476
This PR fixes two pretty big issues with the Svelte adapter:
Preserving state
The first issue is that the
preserveState
option was never implemented in the Svelte adapter, which ultimately meant that preserving state was always enabled. This is quite problematic, since it can cause stale local component data when visiting another page that uses the same page component. For example, when navigating from one edit user page to another.This has been resolved by adding a component key to the page component when rendering it. This is exactly the same way that the Vue and React adapters work. However, adding the
{#key}
block was tricky, since the page and layout components were being dynamically rendered via theRender
component. Which brings us to the next issue...Page store
The second issue was related to accessing the global derived page store (
$page
) in non-page components, such as layouts. For some reason the store was updating prior to non-page components being unmounted, which was causing errors in those components if they depended on the data in that store. For example, in a layout component that expects an authenticated user ($page.auth.user
), when you logout, the$page.auth
was being set tonull
before the layout was being unmounted, causing an error. The workaround here was to always conditionally check for this data in those components, but that's annoying to have to do.I was not able to determine exactly why this was happening, but I think it had to do with how we were using the
<svelte:self>
component within theRender
component. This was a very clever hack by @pedroborges, which allowed us to have unlimited nested persistent layouts. However, I think this somehow messed with Svelte's rendering, causing these issues with the$page
store.To solve this I took a simpler approach, and just manually rendered the page and persistent layouts. This fixes the
$page
store issues, and also allowed me to add a component key to the page component. The tradeoff here is that you can no longer have unlimited nested persistent layouts. You can now only have five. I think this is an non-issue, since I'd be highly surprised if anyone ever had more than 2-3 nested layouts.