You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* failing test for shadowed pages
* find shadowed pages
* store endpoint filename
* update unit tests
* load shadow data
* add shadow request handler type
* fix types
* basic shadow endpoint working with SSR
* implement __data.json
* serialize shadow props
* load shadow props in hydration and client-side navigation
* lint
* lint
* unfocus test
* handle redirects
* more tests
* generate __data.json files when prerendering
* prevent prerendering of pages shadowed by non-GET methods
* lint
* changeset
* remove old shadowing test
* start simplifying todos page in default template
* content negotiation
* mark shadow endpoint as dependency of page
* lint
* revert changes for CI
* tweak enhance signature
* update docs
* more docs
* mention accept: application/json
* undo template change that was for local testing
* Update documentation/docs/03-loading.md
* Update packages/create-svelte/templates/default/svelte.config.js
Co-authored-by: Conduitry <[email protected]>
* safer DATA_SUFFIX
* remove comment, we decided on a 405
Co-authored-by: Conduitry <[email protected]>
@@ -39,17 +39,23 @@ A file called either `src/routes/about.svelte` or `src/routes/about/index.svelte
39
39
<p>TODO...</p>
40
40
```
41
41
42
-
Dynamic parameters are encoded using `[brackets]`. For example, a blog post might be defined by `src/routes/blog/[slug].svelte`. Soon, we'll see how to access that parameter in a [load function](#loading) or the [page store](#modules-$app-stores).
42
+
Dynamic parameters are encoded using `[brackets]`. For example, a blog post might be defined by `src/routes/blog/[slug].svelte`.
43
43
44
44
A file or directory can have multiple dynamic parts, like `[id]-[category].svelte`. (Parameters are 'non-greedy'; in an ambiguous case like `x-y-z`, `id` would be `x` and `category` would be `y-z`.)
45
45
46
46
### Endpoints
47
47
48
-
Endpoints are modules written in `.js` (or `.ts`) files that export functions corresponding to HTTP methods.
48
+
Endpoints are modules written in `.js` (or `.ts`) files that export functions corresponding to HTTP methods. Their job is to allow pages to read and write data that is only available on the server (for example in a database, or on the filesystem).
49
49
50
50
```ts
51
-
// Declaration types for Endpoints
52
-
// * declarations that are not exported are for internal use
51
+
// Type declarations for endpoints (declarations marked with
52
+
// an `export` keyword can be imported from `@sveltejs/kit`)
> See the [TypeScript](#typescript) section for information on `App.Locals` and `App.Platform`.
82
82
83
-
For example, our hypothetical blog page, `/blog/cool-article`, might request data from `/blog/cool-article.json`, which could be represented by a`src/routes/blog/[slug].json.js` endpoint:
83
+
A page like `src/routes/items/[id].svelte`could get its data from`src/routes/items/[id].js`:
> All server-side code, including endpoints, has access to `fetch` in case you need to request data from external APIs.
105
+
> All server-side code, including endpoints, has access to `fetch` in case you need to request data from external APIs. Don't worry about the `$lib` import, we'll get to that [later](#modules-$lib).
109
106
110
107
The job of this function is to return a `{ status, headers, body }` object representing the response, where `status` is an [HTTP status code](https://httpstatusdogs.com):
111
108
@@ -114,30 +111,94 @@ The job of this function is to return a `{ status, headers, body }` object repre
114
111
-`4xx` — client error
115
112
-`5xx` — server error
116
113
117
-
If the returned `body` is an object, and no `content-type` header is returned, it will automatically be turned into a JSON response. (Don't worry about `$lib`, we'll get to that [later](#modules-$lib).)
118
-
119
114
> If `{fallthrough: true}` is returned SvelteKit will [fall through](#routing-advanced-fallthrough-routes) to other routes until something responds, or will respond with a generic 404.
120
115
121
-
For endpoints that handle other HTTP methods, like POST, export the corresponding function:
116
+
The returned `body` corresponds to the page's props:
117
+
118
+
```svelte
119
+
<script>
120
+
// populated with data from the endpoint
121
+
export let item;
122
+
</script>
123
+
124
+
<h1>{item.title}</h1>
125
+
```
126
+
127
+
#### POST, PUT, PATCH, DELETE
128
+
129
+
Endpoints can handle any HTTP method — not just `GET` — by exporting the corresponding function:
122
130
123
131
```js
124
132
exportfunctionpost(event) {...}
133
+
exportfunctionput(event) {...}
134
+
exportfunctionpatch(event) {...}
135
+
exportfunctiondel(event) {...} // `delete` is a reserved word
125
136
```
126
137
127
-
Since `delete` is a reserved word in JavaScript, DELETE requests are handled with a `del` function.
138
+
These functions can, like `get`, return a `body` that will be passed to the page as props. Whereas 4xx/5xx responses from `get` will result in an error page rendering, similar responses to non-GET requests do not, allowing you to do things like render form validation errors:
128
139
129
-
> We don't interact with the `req`/`res` objects you might be familiar with from Node's `http` module or frameworks like Express, because they're only available on certain platforms. Instead, SvelteKit translates the returned object into whatever's required by the platform you're deploying your app to.
140
+
```js
141
+
// src/routes/items.js
142
+
import*asdbfrom'$lib/database';
130
143
131
-
To set multiple cookies in a single set of response headers, you can return an array:
144
+
exportasyncfunctionget() {
145
+
constitems=awaitdb.list();
132
146
133
-
```js
134
-
return {
135
-
headers: {
136
-
'set-cookie': [cookie1, cookie2]
147
+
return {
148
+
body: { items }
149
+
};
150
+
}
151
+
152
+
exportasyncfunctionpost({ request }) {
153
+
const [errors, item] =awaitdb.create(request);
154
+
155
+
if (errors) {
156
+
// return validation errors
157
+
return {
158
+
status:400,
159
+
body: { errors }
160
+
};
137
161
}
138
-
};
162
+
163
+
// redirect to the newly created item
164
+
return {
165
+
status:303,
166
+
headers: {
167
+
location:`/items/${item.id}`
168
+
}
169
+
};
170
+
}
171
+
```
172
+
173
+
```svelte
174
+
<!-- src/routes/items.svelte -->
175
+
<script>
176
+
// The page always has access to props from `get`...
177
+
export let items;
178
+
179
+
// ...plus props from `post` when the page is rendered
180
+
// in response to a POST request, for example after
181
+
// submitting the form below
182
+
export let errors;
183
+
</script>
184
+
185
+
{#each items as item}
186
+
<Preview item={item}/>
187
+
{/each}
188
+
189
+
<form method="post">
190
+
<input name="title">
191
+
192
+
{#if errors?.title}
193
+
<p class="error">{errors.title}</p>
194
+
{/if}
195
+
196
+
<button type="submit">Create item</button>
197
+
</form>
139
198
```
140
199
200
+
If you request the route with an `accept: application/json` header, SvelteKit will render the endpoint data as JSON, rather than the page as HTML.
201
+
141
202
#### Body parsing
142
203
143
204
The `request` object is an instance of the standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) class. As such, accessing the request body is easy:
Endpoints can set cookies by returning a `headers` object with `set-cookie`. To set multiple cookies simultaneously, return an array:
215
+
216
+
```js
217
+
return {
218
+
headers: {
219
+
'set-cookie': [cookie1, cookie2]
220
+
}
221
+
};
222
+
```
223
+
151
224
#### HTTP method overrides
152
225
153
226
HTML `<form>` elements only support `GET` and `POST` methods natively. You can allow other methods, like `PUT` and `DELETE`, by specifying them in your [configuration](#configuration-methodoverride) and adding a `_method=VERB` parameter (you can configure the name) to the form's `action`:
@@ -171,15 +244,21 @@ export default {
171
244
172
245
> Using native `<form>` behaviour ensures your app continues to work when JavaScript fails or is disabled.
173
246
247
+
### Standalone endpoints
248
+
249
+
Most commonly, endpoints exist to provide data to the page with which they're paired. They can, however, exist separately from pages. Standalone endpoints have slightly more flexibility over the returned `body` type — in addition to objects, they can return a string or a `Uint8Array`.
250
+
251
+
> Support for streaming request and response bodies is [coming soon](https://github.com/sveltejs/kit/issues/3419).
252
+
174
253
### Private modules
175
254
176
255
Files and directories with a leading `_` or `.` (other than [`.well-known`](https://en.wikipedia.org/wiki/Well-known_URI)) are private by default, meaning that they do not create routes (but can be imported by files that do). You can configure which modules are considered public or private with the [`routes`](#configuration-routes) configuration.
177
256
178
-
### Advanced
257
+
### Advanced routing
179
258
180
259
#### Rest parameters
181
260
182
-
A route can have multiple dynamic parameters, for example `src/routes/[category]/[item].svelte` or even `src/routes/[category]-[item].svelte`. If the number of route segments is unknown, you can use rest syntax — for example you might implement GitHub's file viewer like so...
261
+
A route can have multiple dynamic parameters, for example `src/routes/[category]/[item].svelte` or even `src/routes/[category]-[item].svelte`. (Parameters are 'non-greedy'; in an ambiguous case like `/x-y-z`, `category` would be `x` and `item` would be `y-z`.) If the number of route segments is unknown, you can use rest syntax — for example you might implement GitHub's file viewer like so...
Copy file name to clipboardExpand all lines: documentation/docs/03-loading.md
+24-22Lines changed: 24 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -2,15 +2,22 @@
2
2
title: Loading
3
3
---
4
4
5
-
A component that defines a page or a layout can export a `load` function that runs before the component is created. This function runs both during server-side rendering and in the client, and allows you to get data for a page without (for example) showing a loading spinner and fetching data in `onMount`.
5
+
A component that defines a page or a layout can export a `load` function that runs before the component is created. This function runs both during server-side rendering and in the client, and allows you to fetch and manipulate data before the page is rendered, thus preventing loading spinners.
6
+
7
+
If the data for a page comes from its endpoint, you may not need a `load` function. It's useful when you need more flexibility, for example loading data from an external API.
6
8
7
9
```ts
8
-
// Declaration types for Loading
9
-
// * declarations that are not exported are for internal use
10
+
// Type declarations for `load` (declarations marked with
11
+
// an `export` keyword can be imported from `@sveltejs/kit`)
> Note the `<script context="module">` — this is necessary because `load` runs before the component is rendered. Code that is per-component instance should go into a second `<script>` tag.
66
64
67
-
`load` is similar to `getStaticProps` or `getServerSideProps` in Next.js, except that it runs on both the server and the client.
65
+
`load` is similar to `getStaticProps` or `getServerSideProps` in Next.js, except that it runs on both the server and the client. In the example above, if a user clicks on a link to this page the data will be fetched from `cms.example.com` without going via our server.
68
66
69
67
If `load` returns `{fallthrough: true}`, SvelteKit will [fall through](#routing-advanced-fallthrough-routes) to other routes until something responds, or will respond with a generic 404.
70
68
@@ -88,7 +86,7 @@ It is recommended that you not store pre-request state in global variables, but
88
86
89
87
### Input
90
88
91
-
The `load` function receives an object containing five fields — `url`, `params`, `fetch`, `session` and `stuff`. The `load` function is reactive, and will re-run when its parameters change, but only if they are used in the function. Specifically, if `url`, `session` or `stuff` are used in the function, they will be re-run whenever their value changes, and likewise for the individual properties of `params`.
89
+
The `load` function receives an object containing five fields — `url`, `params`, `props`, `fetch`, `session` and `stuff`. The `load` function is reactive, and will re-run when its parameters change, but only if they are used in the function. Specifically, if `url`, `session` or `stuff` are used in the function, they will be re-run whenever their value changes, and likewise for the individual properties of `params`.
92
90
93
91
> Note that destructuring parameters in the function declaration is enough to count as using them.
94
92
@@ -111,6 +109,10 @@ For a route filename example like `src/routes/a/[b]/[...c]` and a `url.pathname`
111
109
}
112
110
```
113
111
112
+
#### props
113
+
114
+
If the page you're loading has an endpoint, the data returned from it is accessible inside the leaf component's `load` function as `props`. For layout components and pages without endpoints, `props` will be an empty object.
115
+
114
116
#### fetch
115
117
116
118
`fetch` is equivalent to the native `fetch` web API, and can make credentialed requests. It can be used across both client and server contexts.
@@ -109,7 +104,6 @@ This function takes the `event` object and returns a `session` object that is [a
109
104
If unimplemented, session is `{}`.
110
105
111
106
```ts
112
-
// Declaration types for getSession hook
113
107
exportinterfaceGetSession {
114
108
(event:RequestEvent):MaybePromise<App.Session>;
115
109
}
@@ -142,8 +136,6 @@ This function allows you to modify (or replace) a `fetch` request for an externa
142
136
For example, your `load` function might make a request to a public URL like `https://api.yourapp.com` when the user performs a client-side navigation to the respective page, but during SSR it might make sense to hit the API directly (bypassing whatever proxies and load balancers sit between it and the public internet).
0 commit comments