Skip to content

Commit 6f36aef

Browse files
docs: Elaborate on credentialed fetch behaviour (#10421)
1 parent dcf981c commit 6f36aef

File tree

5 files changed

+39
-19
lines changed

5 files changed

+39
-19
lines changed

.changeset/orange-roses-destroy.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
docs: Elaborate on credentialed `fetch` behaviour

documentation/docs/20-core-concepts/20-load.md

+18-7
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,11 @@ Given a `route.id` of `/a/[b]/[...c]` and a `url.pathname` of `/a/x/y/z`, the `p
231231

232232
To get data from an external API or a `+server.js` handler, you can use the provided `fetch` function, which behaves identically to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch) with a few additional features:
233233

234-
- it can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request
235-
- it can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context)
236-
- internal requests (e.g. for `+server.js` routes) go direct to the handler function when running on the server, without the overhead of an HTTP call
237-
- during server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](hooks#server-hooks-handle). Then, during hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request - if you got a warning in your browser console when using the browser `fetch` instead of the `load` `fetch`, this is why.
234+
- It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request.
235+
- It can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context).
236+
- Internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call.
237+
- During server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](hooks#server-hooks-handle).
238+
- During hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request - if you received a warning in your browser console when using the browser `fetch` instead of the `load` `fetch`, this is why.
238239

239240
```js
240241
/// file: src/routes/items/[id]/+page.js
@@ -247,9 +248,7 @@ export async function load({ fetch, params }) {
247248
}
248249
```
249250

250-
> Cookies will only be passed through if the target host is the same as the SvelteKit application or a more specific subdomain of it.
251-
252-
## Cookies and headers
251+
## Cookies
253252

254253
A server `load` function can get and set [`cookies`](types#public-types-cookies).
255254

@@ -274,8 +273,20 @@ export async function load({ cookies }) {
274273
}
275274
```
276275

276+
Cookies will only be passed through the provided `fetch` function if the target host is the same as the SvelteKit application or a more specific subdomain of it.
277+
278+
For example, if SvelteKit is serving my.domain.com:
279+
- domain.com WILL NOT receive cookies
280+
- my.domain.com WILL receive cookies
281+
- api.domain.dom WILL NOT receive cookies
282+
- sub.my.domain.com WILL receive cookies
283+
284+
Other cookies will not be passed when `credentials: 'include'` is set, because SvelteKit does not know which domain which cookie belongs to (the browser does not pass this information along), so it's not safe to forward any of them. Use the [handleFetch hook](hooks#server-hooks-handlefetch) to work around it.
285+
277286
> When setting cookies, be aware of the `path` property. By default, the `path` of a cookie is the current pathname. If you for example set a cookie at page `admin/user`, the cookie will only be available within the `admin` pages by default. In most cases you likely want to set `path` to `'/'` to make the cookie available throughout your app.
278287
288+
## Headers
289+
279290
Both server and universal `load` functions have access to a `setHeaders` function that, when running on the server, can set headers for the response. (When running in the browser, `setHeaders` has no effect.) This is useful if you want the page to be cached, for example:
280291

281292
```js

documentation/docs/20-core-concepts/50-state-management.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const actions = {
3636

3737
The `user` variable is shared by everyone who connects to this server. If Alice submitted an embarrassing secret, and Bob visited the page after her, Bob would know Alice's secret. In addition, when Alice returns to the site later in the day, the server may have restarted, losing her data.
3838

39-
Instead, you should _authenticate_ the user using [`cookies`](load#cookies-and-headers) and persist the data to a database.
39+
Instead, you should _authenticate_ the user using [`cookies`](load#cookies) and persist the data to a database.
4040

4141
## No side-effects in load
4242

packages/kit/src/exports/public.d.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -697,13 +697,13 @@ export interface LoadEvent<
697697
/**
698698
* `fetch` is equivalent to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch), with a few additional features:
699699
*
700-
* - it can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request
701-
* - it can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context)
702-
* - internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call
703-
* - during server-side rendering, the response will be captured and inlined into the rendered HTML. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](https://kit.svelte.dev/docs/hooks#server-hooks-handle)
704-
* - during hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request
700+
* - It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request.
701+
* - It can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context).
702+
* - Internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call.
703+
* - During server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](https://kit.svelte.dev/docs/hooks#server-hooks-handle)
704+
* - During hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request.
705705
*
706-
* > Cookies will only be passed through if the target host is the same as the SvelteKit application or a more specific subdomain of it.
706+
* You can learn more about making credentialed requests with cookies [here](https://kit.svelte.dev/docs/load#cookies)
707707
*/
708708
fetch: typeof fetch;
709709
/**
@@ -949,11 +949,13 @@ export interface RequestEvent<
949949
/**
950950
* `fetch` is equivalent to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch), with a few additional features:
951951
*
952-
* - it can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request
953-
* - it can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context)
954-
* - internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call
952+
* - It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request.
953+
* - It can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context).
954+
* - Internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call.
955+
* - During server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](https://kit.svelte.dev/docs/hooks#server-hooks-handle)
956+
* - During hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request.
955957
*
956-
* > Cookies will only be passed through if the target host is the same as the SvelteKit application or a more specific subdomain of it.
958+
* You can learn more about making credentialed requests with cookies [here](https://kit.svelte.dev/docs/load#cookies)
957959
*/
958960
fetch: typeof fetch;
959961
/**

packages/kit/src/runtime/server/fetch.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,16 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
5151
}
5252

5353
if (url.origin !== event.url.origin) {
54-
// allow cookie passthrough for "same-origin"
54+
// Allow cookie passthrough for "credentials: same-origin" and "credentials: include"
5555
// if SvelteKit is serving my.domain.com:
5656
// - domain.com WILL NOT receive cookies
5757
// - my.domain.com WILL receive cookies
5858
// - api.domain.dom WILL NOT receive cookies
5959
// - sub.my.domain.com WILL receive cookies
6060
// ports do not affect the resolution
6161
// leading dot prevents mydomain.com matching domain.com
62+
// Do not forward other cookies for "credentials: include" because we don't know
63+
// which cookie belongs to which domain (browser does not pass this info)
6264
if (`.${url.hostname}`.endsWith(`.${event.url.hostname}`) && credentials !== 'omit') {
6365
const cookie = get_cookie_header(url, request.headers.get('cookie'));
6466
if (cookie) request.headers.set('cookie', cookie);

0 commit comments

Comments
 (0)