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

SvelteKit: Fragment stores become empty after hydration when using +page.server.ts server-side loading alongside +layout.gql #1314

Closed
nermolov opened this issue Jul 3, 2024 · 5 comments

Comments

@nermolov
Copy link

nermolov commented Jul 3, 2024

Describe the bug

On one page in my SvelteKit application, I need to conditionally call a private API based on the response of my GraphQL query, so I switched from using a +page.gql query to a manual server only load as described in the documentation. I still have a standard client/server query in my global +layout.gql file. It seems that the combination of these two causes my page-level fragment stores to get cleared out after initial hydration, despite the fact that all of the data is still there.

page.gql:

query AnimeQuery {
  Media(isAdult: false) {
    ...AnimeTitleFragment
  }
}

+page.server.ts:

import { AnimeQueryStore } from '$houdini';
import type { PageServerLoad } from './$houdini';

export const load: PageServerLoad = async (event) => {
  const myQuery = new AnimeQueryStore();
  const { data } = await myQuery.fetch({ event });

  return { data };
};

+page.svelte:

<script lang="ts">
  import AnimeTitle from '$lib/AnimeTitle.svelte';
  import type { PageData } from './$houdini';

  export let data: PageData;
</script>

<AnimeTitle animeTitle={data?.data?.Media} />

<h3>Contents of `data`</h3>
<pre>{JSON.stringify(data, null, 2)}</pre>

AnimeTitle.svelte:

<script lang="ts">
  import { fragment, graphql, type AnimeTitleFragment } from '$houdini';

  export let animeTitle: AnimeTitleFragment | null | undefined;
  $: animeTitleFragment = fragment(
    animeTitle,
    graphql`
      fragment AnimeTitleFragment on Media {
        title {
          romaji
          english
          native
        }
      }
    `
  );
</script>

<h1>{$animeTitleFragment?.title?.english}</h1>

+layout.gql:

query LayoutQuery {
  Character(search: "Spike") {
    name {
      full
    }
  }
}

+layout.svelte:

<script lang="ts">
  import type { LayoutData } from './$houdini';

  export let data: LayoutData;
  $: ({ LayoutQuery } = data);
</script>

<p>{$LayoutQuery?.data?.Character?.name?.full}</p>
<slot />

SSR page/with javascript disabled/before hydration:
image

Page with javascript enabled/after hydration:
image

The above code is included in the linked minimal reproduction repository.

Reproduction

https://github.com/nermolov/sveltekit-houdini-server-load

@AlecAivazis
Copy link
Collaborator

Huh that's strange. Sorry for lagging on the reply here and thanks for taking the time to put together a reproduction. I'll try to find some time to look into it in the next few days

@AlecAivazis
Copy link
Collaborator

Okay, I finally found the time and have a good idea of what's going on. Since you are loading your graphql query on the server, the client-side cache does not access to that data and so when the app hydrates and tries to hook up to the cache, it doesn't have anything.

I'm not quite sure what the correct work around is for this just yet but I will keep thinking on it. Until then, the only real option is to either not load the data on a server file, or to not use the fragment.

@AlecAivazis
Copy link
Collaborator

i'm going to close this in favor of #675

@nermolov
Copy link
Author

@AlecAivazis is there a way to manually inject data into the client side cache?

@nermolov
Copy link
Author

nermolov commented Aug 14, 2024

I've decided to use the following workaround in all of my fragment components for this route nermolov/sveltekit-houdini-server-load@b39633a seems to work fine given that all of the relevant data is only loaded once for this route/there are no mutations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants