mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-15 20:34:44 +00:00
update docs
This commit is contained in:
@@ -2,46 +2,37 @@
|
||||
title: Preloading
|
||||
---
|
||||
|
||||
As seen in the [routing](guide#routing) section, top-level page components can have a `preload` function that will load some data that the page depends on. This is similar to `getInitialProps` in Next.js or `asyncData` in Nuxt.js.
|
||||
As seen in the [routing](docs#routing) section, page components can have an optional `preload` function that will load some data that the page depends on. This is similar to `getInitialProps` in Next.js or `asyncData` in Nuxt.js.
|
||||
|
||||
```html
|
||||
<script>
|
||||
export default {
|
||||
preload({ params, query }) {
|
||||
const { slug } = params;
|
||||
<script context="module">
|
||||
export async function preload(page, session) {
|
||||
const { slug } = page.params;
|
||||
|
||||
return this.fetch(`blog/${slug}.json`).then(r => r.json()).then(article => {
|
||||
return { article };
|
||||
});
|
||||
}
|
||||
};
|
||||
const res = await this.fetch(`blog/${slug}.json`);
|
||||
const article = await res.json();
|
||||
|
||||
return { article };
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Your `preload` function is optional; whether or not you include it, the component will have access to the `query` and `params` objects, on top of any [default data](https://svelte.technology/guide#default-data) specified with a `data` property.
|
||||
|
||||
The top-level `_layout.html` component is rendered with a `preloading` value: `true` during preloading, `false` otherwise. This value is useful to display a loading spinner or otherwise indicate that a navigation is in progress.
|
||||
|
||||
```html
|
||||
<!-- src/routes/_layout.html -->
|
||||
{#if preloading}
|
||||
<div>Loading...</div>
|
||||
{/if}
|
||||
|
||||
<svelte:component this={child.component} {...child.props}/>
|
||||
```
|
||||
|
||||
The `preloading` value is only set during page navigations. Prefetching (see [below](guide#prefetching)) does not set `preloading` since it is intended to be transparent to the user.
|
||||
It lives in a `context="module"` script — see the [tutorial](https://svelte.dev/tutorial/module-exports) — because it's not part of the component instance itself; instead, it runs *before* the component is created, allowing you to avoid flashes while data is fetched.
|
||||
|
||||
### Argument
|
||||
|
||||
The `preload` function receives a `{ params, query }` object where `params` is derived from the URL and the route filename, and `query` is an object of values in the query string.
|
||||
The `preload` function receives two arguments — `page` and `session`.
|
||||
|
||||
So if the example above was `src/routes/blog/[slug].html` and the URL was `/blog/some-post?foo=bar&baz`, the following would be true:
|
||||
`page` is a `{ path, params, query }` object where `path` is the URL's pathname, `params` is derived from `path` and the route filename, and `query` is an object of values in the query string.
|
||||
|
||||
* `params.slug === 'some-post'`
|
||||
* `query.foo === 'bar'`
|
||||
* `query.baz === true`
|
||||
So if the example above was `src/routes/blog/[slug].svelte` and the URL was `/blog/some-post?foo=bar&baz`, the following would be true:
|
||||
|
||||
* `page.path === '/blog/some-post'`
|
||||
* `page.params.slug === 'some-post'`
|
||||
* `page.query.foo === 'bar'`
|
||||
* `page.query.baz === true`
|
||||
|
||||
`session` is generated on the server by the `session` option passed to `sapper.middleware` (TODO this needs further documentation. Perhaps a server API section?)
|
||||
|
||||
|
||||
### Return value
|
||||
@@ -52,14 +43,12 @@ When Sapper renders a page on the server, it will attempt to serialize the resol
|
||||
|
||||
### Context
|
||||
|
||||
Inside `preload`, you have access to three methods...
|
||||
Inside `preload`, you have access to three methods:
|
||||
|
||||
* `this.fetch(url, options)`
|
||||
* `this.error(statusCode, error)`
|
||||
* `this.redirect(statusCode, location)`
|
||||
|
||||
...and `this.store`, if you're using [state management](guide#state-management).
|
||||
|
||||
|
||||
#### this.fetch
|
||||
|
||||
@@ -68,16 +57,14 @@ In browsers, you can use `fetch` to make AJAX requests, for getting data from yo
|
||||
To fix this, Sapper provides `this.fetch`, which works on the server as well as in the client:
|
||||
|
||||
```html
|
||||
<script>
|
||||
export default {
|
||||
preload() {
|
||||
return this.fetch(`secret-data.json`, {
|
||||
credentials: 'include'
|
||||
}).then(r => {
|
||||
// ...
|
||||
});
|
||||
}
|
||||
};
|
||||
<script context="module">
|
||||
export async function preload() {
|
||||
const res = await this.fetch(`secret-data.json`, {
|
||||
credentials: 'include'
|
||||
});
|
||||
|
||||
// ...
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -89,23 +76,19 @@ Note that you will need to use session middleware such as [express-session](http
|
||||
If the user navigated to `/blog/some-invalid-slug`, we would want to render a 404 Not Found page. We can do that with `this.error`:
|
||||
|
||||
```html
|
||||
<script>
|
||||
export default {
|
||||
preload({ params, query }) {
|
||||
const { slug } = params;
|
||||
<script context="module">
|
||||
export async function preload({ params, query }) {
|
||||
const { slug } = params;
|
||||
|
||||
return this.fetch(`blog/${slug}.json`).then(r => {
|
||||
// assume all responses are either 200 or 404
|
||||
if (r.status === 200) {
|
||||
return r.json().then(article => {
|
||||
return { article };
|
||||
});
|
||||
} else {
|
||||
this.error(404, 'Not found');
|
||||
}
|
||||
});
|
||||
const res = await this.fetch(`blog/${slug}.json`);
|
||||
|
||||
if (res.status === 200) {
|
||||
const article = await res.json();
|
||||
return { article };
|
||||
}
|
||||
};
|
||||
|
||||
this.error(404, 'Not found');
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -117,19 +100,15 @@ The same applies to other error codes you might encounter.
|
||||
You can abort rendering and redirect to a different location with `this.redirect`:
|
||||
|
||||
```html
|
||||
<script>
|
||||
export default {
|
||||
preload({ params, session }) {
|
||||
const { user } = this.store.get();
|
||||
<script context="module">
|
||||
export async function preload(page, session) {
|
||||
const { user } = session;
|
||||
|
||||
if (!user) {
|
||||
return this.redirect(302, 'login');
|
||||
}
|
||||
|
||||
return {
|
||||
user
|
||||
};
|
||||
if (!user) {
|
||||
return this.redirect(302, 'login');
|
||||
}
|
||||
};
|
||||
|
||||
return { user };
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user