3

How to access to the page params in context="module" and using {#await load()} blocks?

If I do NOT use {#await load()} block I don't get error and page works correctly, but if I use Await block I get this error:

*Cannot read properties of undefined (reading 'params')*

(I have to mention that I can see the result of console.log in script tag)
(I'm using Await block to load a spinner before completing the content load)

This is the code:

<script context="module">
    import { gql, GraphQLClient } from 'graphql-request';

    export async function load(ctx) {
        const pageSlug = await ctx.params.slug;
        const graphcms = new GraphQLClient(import.meta.env.VITE_GRAPHCMS_URL, {
            headers: {}
        });

        const getArticleQuery = gql`
            query getArticle {
                articles(filters: { Slug: { eq: "${pageSlug}" } }) {
                    data {
                        id
                        attributes {
                            Title
                            Slug
                            Content
                            FeaturedImage {
                                data {
                                    attributes {
                                        url
                                    }
                                }
                            }
                        }
                    }
                }
            }
        `;

        const data = await graphcms.request(getArticleQuery);

        if (data) {
            return {
                props: {
                    article: data.articles.data[0],
                    pageSlug: pageSlug
                }
            };
        } else {
            throw new Error(data);
        }
    }
</script>

<script>
    import { Jumper } from 'svelte-loading-spinners';
    export let article;
    export let pageSlug;
    $: console.log('pageSlug', pageSlug);
</script>

{#await load()}
        <div class="flex justify-center items-center">
            <Jumper size="60" color="#FF3E00" unit="px" duration="1s" />
        </div>
    {:then data}
        <span>{article.attributes.Title}</span>
        <span>{JSON.stringify(pageSlug)}</span>
    {:catch error}
        <p style="color: red">{error.message}</p>
{/await}

Sarah Diba
  • 87
  • 1
  • 9

1 Answers1

3

This is not how load works.

The load function runs before the page is mounted and the resulting props are passed to the page. It will run on the server for the very first page you visit and on the client for all subsequent pages.

If you absolutely need to have a loading spinner before showing the content, you have to load the data on the client and the client alone. This can be done by loading the data in the onMount function instead, but you lose the benefits of server side rendering.

Stephane Vanraes
  • 14,343
  • 2
  • 23
  • 41
  • Thank your for your detailed answer. I've removed parentheses from the `{await load()}` and it works perfectly. But I'm not sure about SSR (when I use Ctrl+U and see the source I see that all the data is loaded fully without problem ; is this SSR?). Is this a good way to load page? – Sarah Diba Feb 21 '22 at 22:22