13

If the file test.svelte below is a Page in /routes, it successfully calls load() and populates the template with the JSON array it retrieves when I access it via http://localhost:3000/test. If I move this file to /lib and import it as a component in /routes/index.svelte, the load() method of the component never runs when I go to http://localhost:3000.

test.svelte

<script context="module" lang="ts">
  /**
     * @type {import('@sveltejs/kit').Load}
   */
  export async function load({ fetch }) {
    const url = '/api/announcement'
    const res: Response = await fetch(url)

    if (res.ok) {
      const sections: Announcement[] = await res.json()
      return {
        props: {
          sections
        }
      }
    }

    return {
      status: res.status,
      error: new Error(`Could not load ${url}`)
     }
  }
</script>

<script lang="ts">
  export let sections: Announcement[] = []
</script>

<template>
  {#each sections as section}
    <p>
      {section.title}<br/>
      {section.description}
    </p>
  {/each}
</template>

Here is routes/index.svelte that tries to load it as a component from /lib:

<script context="module" lang="ts">
  import Test from '$lib/test.svelte'
</script>

<template lang="pug">
  .container
    Test
</template>

Seems like I'm doing something obviously wrong but I'm new to Svelte and SvelteKit. While I considered retrieving the data in routes/index.svelte and pass it down to the component, I was hoping to encapsulate the data retrieval in the component to keep it simpler.

2 Answers 2

20

The docs state (emphasis mine)

A component that defines a page or a layout can export a load function that runs before the component is created.

This means you cannot use the load function in a regular component.

You can however still use onMount, to load data when the component is mounted.

Alternatively, you keep the load function in your page and pass the retrieved values to the component itself.

If you really do not want a large load function in your page, you can also put it in a third file (loader.js) and import it from there in the page (in the end the load function has to be in the page)

<script context="module">
  import _load from './loader.js';
  export const load = _load;
</script>

edit 31.5.2023

The above solution works fine for SvelteKit on the date of the answer, in later version the load function has been extracted to it's own file +page.js (or +layout.js) for which the details can be found in the documentation.
The basic principle however stays the same: loading data is for pages and layouts only, components take their data from props (or alternatively from a fetch in the onMount)

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks - found that one-liner last night in the docs. Was originally thinking my announcements component could get its own data and sounds like I can still do this with onMount(). But is this a pattern I should avoid? My announcements component just displays data that is not changing very frequently.
easiest way is to just pass the data with setContext and getContext
this answer makes me sad :'(
@stephane Could you elaborate on how to use onMount in this situation?
1

Adding a little bit of more visualization to the Stephane's answer above.

For example: If you have a main page and you need to redirect to the /login

src/
└── routes/
    ├── +page.svelte        // Entry Point
    ├── +page.js            // Js file of your entry point
    └── login/
        └── +page.svelte    // Login page

.svelte: Defines the component's user interface and behavior.

.js or .ts: Handles data loading logic, redirects, and other functionality before rendering the component.

And, in your .js file you just need to add the load function

import { redirect } from '@sveltejs/kit';

export const load = async () => {
  throw redirect(307, '/login');
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.