Load data
Before a template can be rendered, it needs data.
In Crelte, data is loaded in a structured way based on the current route and entry.
Two GraphQL queries are generally loaded automatically for every request:
global.graphql— global, cross-page dataentry.graphql— data for the currently resolved entry
Additional data can be loaded by exporting loadGlobalData or loadEntryData from App.svelte or loadData from you components.
Data loading lifecycle
Data loading happens in the following order:
Global data
global.graphqlis loaded first, together withentry.graphql.Entry data
After the entry has been resolved, the active template’sloadDataand its children is executed.
All load functions run on both the server and the client, allowing pages to be server-rendered and then transition to a single-page application.
loadGlobalData
loadGlobalData is used to load data that does not depend on the current entry.
It is defined in App.svelte and runs before any template-specific data loading.
Exporting loadGlobalData overrides the default global.graphql query.
<script module>
/** @type {import('crelte').LoadData} */
export const loadGlobalData = {
someApi: () =>
fetch('https://api.example.com')
.then(res => res.json())
};
</script>
<script>
import { getGlobal } from 'crelte';
const someApi = getGlobal('someApi');
</script>Use loadGlobalData for data such as navigation, site-wide configuration, or external APIs that are independent of the current entry and cannot be integrated inside global.graphql.
loadData
Each template can export a loadData definition. It is executed after the entry has been resolved and receives access to both the CrelteRequest and the current entry.
<script module>
import blogsQuery from '@/queries/blogs.graphql';
/** @type {import('crelte').LoadData} */
export const loadData = (cr, entry) =>
cr.query(blogsQuery, {
categories: entry.categories
});
</script>
<script>
let { entries } = $props();
</script>Defining loadData
loadData can be defined in several different ways depending on your needs. All variants are executed in parallel and their results are merged into the component’s props.
Object
This is the most common form. Each property defines a separate data source.
<script module>
import entriesQuery from '@/queries/entries.graphql';
import { headerLoadData } from '@/layout/Header.svelte';
/** @type {import('crelte').LoadData} */
export const loadData = {
entries: entriesQuery,
header: headerLoadData
};
</script>
<script>
let { entries, header } = $props();
</script>GraphQL query
You can export a GraphQL query directly. All named queries inside the file become available as props.
<script module>
import blogsQuery from '@/queries/blogs.graphql';
/** @type {import('crelte').LoadData} */
export const loadData = blogsQuery;
</script>
<script>
let { blogs } = $props();
</script>Function
Using a function provides the most flexibility but is a bit more verbose.
<script module>
import articlesQuery from '@/queries/articles.graphql';
/** @type {import('crelte').LoadDataFn} */
export const loadData = (cr, entry) =>
cr.query(articlesQuery, {
category: entry.category
});
</script>Functions can also be used inside an object definition.
Array
Multiple load definitions can be combined using an array. All entries are executed in parallel and merged.
<script module>
import blogsQuery from '@/queries/blogs.graphql';
import { headerLoadData } from '@/layout/Header.svelte';
/** @type {import('crelte').LoadData} */
export const loadData = [
blogsQuery,
{ header: headerLoadData }
];
</script>
<script>
let { blogs, header } = $props();
</script>Input
loadDatafunctions receive a CrelteRequest instance and the resolvedentry.loadGlobalDatareceives only the CrelteRequest, as the entry is not yet available.
Output
A load function should return an object (or nothing). The returned data is merged into the component’s props.
When to use loadData
Use loadData when data cannot be loaded via global.graphql or entry.graphql.
Prefer extending existing GraphQL queries where possible to avoid unnecessary additional requests.