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
Copy file name to clipboardExpand all lines: apps/svelte.dev/content/docs/kit/10-getting-started/40-web-standards.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -79,7 +79,7 @@ Most of the time, your endpoints will return complete data, as in the `userAgent
79
79
80
80
## URL APIs
81
81
82
-
URLs are represented by the [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) interface, which includes useful properties like `origin` and `pathname` (and, in the browser, `hash`). This interface shows up in various places — `event.url` in [hooks](hooks) and [server routes](routing#server), [`$page.url`]($app-stores) in [pages](routing#page), `from` and `to` in [`beforeNavigate` and `afterNavigate`]($app-navigation) and so on.
82
+
URLs are represented by the [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) interface, which includes useful properties like `origin` and `pathname` (and, in the browser, `hash`). This interface shows up in various places — `event.url` in [hooks](hooks) and [server routes](routing#server), [`page.url`]($app-state) in [pages](routing#page), `from` and `to` in [`beforeNavigate` and `afterNavigate`]($app-navigation) and so on.
> `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$app/stores` instead.
144
+
142
145
SvelteKit will 'walk up the tree' looking for the closest error boundary — if the file above didn't exist it would try `src/routes/blog/+error.svelte` and then `src/routes/+error.svelte` before rendering the default error page. If _that_ fails (or if the error was thrown from the `load` function of the root `+layout`, which sits 'above' the root `+error`), SvelteKit will bail out and render a static fallback error page, which you can customise by creating a `src/error.html` file.
143
146
144
147
If the error occurs inside a `load` function in `+layout(.server).js`, the closest error boundary in the tree is an `+error.svelte` file _above_ that layout (not next to it).
+++ // we can access `data.posts` because it's returned from
126
126
// the parent layout `load` function
127
-
let index = $derived(data.posts.findIndex(post => post.slug === $page.params.slug));
127
+
let index = $derived(data.posts.findIndex(post => post.slug === page.params.slug));
128
128
let next = $derived(data.posts[index + 1]);+++
129
129
</script>
130
130
@@ -138,24 +138,28 @@ Data returned from layout `load` functions is available to child `+layout.svelte
138
138
139
139
> [!NOTE] If multiple `load` functions return data with the same key, the last one 'wins' — the result of a layout `load` returning `{ a: 1, b: 2 }` and a page `load` returning `{ b: 3, c: 4 }` would be `{ a: 1, b: 3, c: 4 }`.
140
140
141
-
## $page.data
141
+
## page.data
142
142
143
143
The `+page.svelte` component, and each `+layout.svelte` component above it, has access to its own data plus all the data from its parents.
144
144
145
-
In some cases, we might need the opposite — a parent layout might need to access page data or data from a child layout. For example, the root layout might want to access a `title` property returned from a `load` function in `+page.js` or `+page.server.js`. This can be done with `$page.data`:
145
+
In some cases, we might need the opposite — a parent layout might need to access page data or data from a child layout. For example, the root layout might want to access a `title` property returned from a `load` function in `+page.js` or `+page.server.js`. This can be done with `page.data`:
146
146
147
147
```svelte
148
148
<!--- file: src/routes/+layout.svelte --->
149
149
<script>
150
-
import { page } from '$app/stores';
150
+
import { page } from '$app/state';
151
151
</script>
152
152
153
153
<svelte:head>
154
-
<title>{$page.data.title}</title>
154
+
<title>{page.data.title}</title>
155
155
</svelte:head>
156
156
```
157
157
158
-
Type information for `$page.data` is provided by `App.PageData`.
158
+
Type information for `page.data` is provided by `App.PageData`.
159
+
160
+
> [!LEGACY]
161
+
> `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$app/stores` instead.
162
+
> It provides a `page` store with the same interface that you can subscribe to, e.g. `$page.data.title`.
Copy file name to clipboardExpand all lines: apps/svelte.dev/content/docs/kit/20-core-concepts/30-form-actions.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -103,7 +103,7 @@ As well as the `action` attribute, we can use the `formaction` attribute on a bu
103
103
104
104
## Anatomy of an action
105
105
106
-
Each action receives a `RequestEvent` object, allowing you to read the data with `request.formData()`. After processing the request (for example, logging the user in by setting a cookie), the action can respond with data that will be available through the `form` property on the corresponding page and through `$page.form` app-wide until the next update.
106
+
Each action receives a `RequestEvent` object, allowing you to read the data with `request.formData()`. After processing the request (for example, logging the user in by setting a cookie), the action can respond with data that will be available through the `form` property on the corresponding page and through `page.form` app-wide until the next update.
107
107
108
108
```js
109
109
/// file: src/routes/login/+page.server.js
@@ -157,7 +157,7 @@ export const actions = {
157
157
158
158
### Validation errors
159
159
160
-
If the request couldn't be processed because of invalid data, you can return validation errors — along with the previously submitted form values — back to the user so that they can try again. The `fail` function lets you return an HTTP status code (typically 400 or 422, in the case of validation errors) along with the data. The status code is available through `$page.status` and the data through `form`:
160
+
If the request couldn't be processed because of invalid data, you can return validation errors — along with the previously submitted form values — back to the user so that they can try again. The `fail` function lets you return an HTTP status code (typically 400 or 422, in the case of validation errors) along with the data. The status code is available through `page.status` and the data through `form`:
161
161
162
162
```js
163
163
/// file: src/routes/login/+page.server.js
@@ -353,7 +353,7 @@ The easiest way to progressively enhance a form is to add the `use:enhance` acti
353
353
354
354
Without an argument, `use:enhance` will emulate the browser-native behaviour, just without the full-page reloads. It will:
355
355
356
-
- update the `form` property, `$page.form` and `$page.status` on a successful or invalid response, but only if the action is on the same page you're submitting from. For example, if your form looks like `<form action="/somewhere/else" ..>`, `form` and `$page` will _not_ be updated. This is because in the native form submission case you would be redirected to the page the action is on. If you want to have them updated either way, use [`applyAction`](#Progressive-enhancement-Customising-use:enhance)
356
+
- update the `form` property, `page.form` and `page.status` on a successful or invalid response, but only if the action is on the same page you're submitting from. For example, if your form looks like `<form action="/somewhere/else" ..>`, the `form`prop and the `page.form` state will _not_ be updated. This is because in the native form submission case you would be redirected to the page the action is on. If you want to have them updated either way, use [`applyAction`](#Progressive-enhancement-Customising-use:enhance)
357
357
- reset the `<form>` element
358
358
- invalidate all data using `invalidateAll` on a successful response
359
359
- call `goto` on a redirect response
@@ -412,7 +412,7 @@ If you return a callback, you may need to reproduce part of the default `use:enh
412
412
413
413
The behaviour of `applyAction(result)` depends on `result.type`:
414
414
415
-
- `success`, `failure` — sets `$page.status` to `result.status` and updates `form` and `$page.form` to `result.data` (regardless of where you are submitting from, in contrast to `update` from `enhance`)
415
+
- `success`, `failure` — sets `page.status` to `result.status` and updates `form` and `page.form` to `result.data` (regardless of where you are submitting from, in contrast to `update` from `enhance`)
Copy file name to clipboardExpand all lines: apps/svelte.dev/content/docs/kit/20-core-concepts/50-state-management.md
+20-17Lines changed: 20 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,7 +41,7 @@ Instead, you should _authenticate_ the user using [`cookies`](load#Cookies) and
41
41
42
42
## No side-effects in load
43
43
44
-
For the same reason, your `load` functions should be _pure_ — no side-effects (except maybe the occasional `console.log(...)`). For example, you might be tempted to write to a store inside a `load` function so that you can use the store value in your components:
44
+
For the same reason, your `load` functions should be _pure_ — no side-effects (except maybe the occasional `console.log(...)`). For example, you might be tempted to write to a store or global state inside a `load` function so that you can use the value in your components:
...and pass it around to the components that need it, or use [`$page.data`](load#$page.data).
80
+
...and pass it around to the components that need it, or use [`page.data`](load#page.data).
81
81
82
82
If you're not using SSR, then there's no risk of accidentally exposing one user's data to another. But you should still avoid side-effects in your `load` functions — your application will be much easier to reason about without them.
83
83
84
-
## Using stores with context
84
+
## Using state and stores with context
85
85
86
-
You might wonder how we're able to use `$page.data` and other [app stores]($app-stores) if we can't use our own stores. The answer is that app stores on the server use Svelte's [context API](/tutorial/svelte/context-api) — the store is attached to the component tree with `setContext`, and when you subscribe you retrieve it with `getContext`. We can do the same thing with our own stores:
86
+
You might wonder how we're able to use `page.data` and other [app state]($app-state) (or [app stores]($app-stores)) if we can't use global state. The answer is that app state and app stores on the server use Svelte's [context API](/tutorial/svelte/context-api) — the state (or store) is attached to the component tree with `setContext`, and when you subscribe you retrieve it with `getContext`. We can do the same thing with our own state:
// ...and add it to the context for child components to access
104
-
setContext('user', user);
96
+
// Pass a function referencing our state
97
+
// to the context for child components to access
98
+
setContext('user', () => data.user);
105
99
</script>
106
100
```
107
101
@@ -114,10 +108,15 @@ You might wonder how we're able to use `$page.data` and other [app stores]($app-
114
108
const user = getContext('user');
115
109
</script>
116
110
117
-
<p>Welcome {$user.name}</p>
111
+
<p>Welcome {user().name}</p>
118
112
```
119
113
120
-
Updating the value of a context-based store in deeper-level pages or components while the page is being rendered via SSR will not affect the value in the parent component because it has already been rendered by the time the store value is updated. In contrast, on the client (when CSR is enabled, which is the default) the value will be propagated and components, pages, and layouts higher in the hierarchy will react to the new value. Therefore, to avoid values 'flashing' during state updates during hydration, it is generally recommended to pass state down into components rather than up.
114
+
> [!NOTE] We're passing a function into `setContext` to keep reactivity across boundaries. Read more about it [here](https://svelte.dev/docs/svelte/$state#Passing-state-into-functions)
115
+
116
+
> [!LEGACY]
117
+
> You also use stores from `svelte/store` for this, but when using Svelte 5 it is recommended to make use of universal reactivity instead.
118
+
119
+
Updating the value of context-based state in deeper-level pages or components while the page is being rendered via SSR will not affect the value in the parent component because it has already been rendered by the time the state value is updated. In contrast, on the client (when CSR is enabled, which is the default) the value will be propagated and components, pages, and layouts higher in the hierarchy will react to the new value. Therefore, to avoid values 'flashing' during state updates during hydration, it is generally recommended to pass state down into components rather than up.
121
120
122
121
If you're not using SSR (and can guarantee that you won't need to use SSR in future) then you can safely keep state in a shared module, without using the context API.
123
122
@@ -164,14 +163,18 @@ Instead, we need to make the value [_reactive_](/tutorial/svelte/state):
164
163
Reusing components like this means that things like sidebar scroll state are preserved, and you can easily animate between changing values. In the case that you do need to completely destroy and remount a component on navigation, you can use this pattern:
If you have state that should survive a reload and/or affect SSR, such as filters or sorting rules on a table, URL search parameters (like `?sort=price&order=ascending`) are a good place to put them. You can put them in `<a href="...">` or `<form action="...">` attributes, or set them programmatically via `goto('?key=value')`. They can be accessed inside `load` functions via the `url` parameter, and inside components via `$page.url.searchParams`.
177
+
If you have state that should survive a reload and/or affect SSR, such as filters or sorting rules on a table, URL search parameters (like `?sort=price&order=ascending`) are a good place to put them. You can put them in `<a href="...">` or `<form action="...">` attributes, or set them programmatically via `goto('?key=value')`. They can be accessed inside `load` functions via the `url` parameter, and inside components via `page.url.searchParams`.
This throws an exception that SvelteKit catches, causing it to set the response status code to 404 and render an [`+error.svelte`](routing#error) component, where `$page.error` is the object provided as the second argument to `error(...)`.
44
+
This throws an exception that SvelteKit catches, causing it to set the response status code to 404 and render an [`+error.svelte`](routing#error) component, where `page.error` is the object provided as the second argument to `error(...)`.
45
45
46
46
```svelte
47
47
<!--- file: src/routes/+error.svelte --->
48
48
<script>
49
-
import { page } from '$app/stores';
49
+
import { page } from '$app/state';
50
50
</script>
51
51
52
-
<h1>{$page.error.message}</h1>
52
+
<h1>{page.error.message}</h1>
53
53
```
54
54
55
+
> [!LEGACY]
56
+
> `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$app/stores` instead.
57
+
55
58
You can add extra properties to the error object if needed...
Copy file name to clipboardExpand all lines: apps/svelte.dev/content/docs/kit/30-advanced/67-shallow-routing.md
+11-8Lines changed: 11 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ SvelteKit makes this possible with the [`pushState`]($app-navigation#pushState)
13
13
<!--- file: +page.svelte --->
14
14
<script>
15
15
import { pushState } from '$app/navigation';
16
-
import { page } from '$app/stores';
16
+
import { page } from '$app/state';
17
17
import Modal from './Modal.svelte';
18
18
19
19
function showModal() {
@@ -23,21 +23,24 @@ SvelteKit makes this possible with the [`pushState`]($app-navigation#pushState)
23
23
}
24
24
</script>
25
25
26
-
{#if $page.state.showModal}
26
+
{#if page.state.showModal}
27
27
<Modal close={() => history.back()} />
28
28
{/if}
29
29
```
30
30
31
-
The modal can be dismissed by navigating back (unsetting `$page.state.showModal`) or by interacting with it in a way that causes the `close` callback to run, which will navigate back programmatically.
31
+
The modal can be dismissed by navigating back (unsetting `page.state.showModal`) or by interacting with it in a way that causes the `close` callback to run, which will navigate back programmatically.
32
32
33
33
## API
34
34
35
35
The first argument to `pushState` is the URL, relative to the current URL. To stay on the current URL, use `''`.
36
36
37
-
The second argument is the new page state, which can be accessed via the [page store]($app-stores#page) as `$page.state`. You can make page state type-safe by declaring an [`App.PageState`](types#PageState) interface (usually in `src/app.d.ts`).
37
+
The second argument is the new page state, which can be accessed via the [page object]($app-state#page) as `page.state`. You can make page state type-safe by declaring an [`App.PageState`](types#PageState) interface (usually in `src/app.d.ts`).
38
38
39
39
To set page state without creating a new history entry, use `replaceState` instead of `pushState`.
40
40
41
+
> [!LEGACY]
42
+
> `page.state` from `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$page.state` from `$app/stores` instead.
43
+
41
44
## Loading data for a route
42
45
43
46
When shallow routing, you may want to render another `+page.svelte` inside the current page. For example, clicking on a photo thumbnail could pop up the detail view without navigating to the photo page.
@@ -48,7 +51,7 @@ For this to work, you need to load the data that the `+page.svelte` expects. A c
48
51
<!--- file: src/routes/photos/+page.svelte --->
49
52
<script>
50
53
import { preloadData, pushState, goto } from '$app/navigation';
51
-
import { page } from '$app/stores';
54
+
import { page } from '$app/state';
52
55
import Modal from './Modal.svelte';
53
56
import PhotoPage from './[id]/+page.svelte';
54
57
@@ -86,17 +89,17 @@ For this to work, you need to load the data that the `+page.svelte` expects. A c
86
89
</a>
87
90
{/each}
88
91
89
-
{#if $page.state.selected}
92
+
{#if page.state.selected}
90
93
<Modal onclose={() => history.back()}>
91
94
<!-- pass page data to the +page.svelte component,
92
95
just like SvelteKit would on navigation -->
93
-
<PhotoPage data={$page.state.selected} />
96
+
<PhotoPage data={page.state.selected} />
94
97
</Modal>
95
98
{/if}
96
99
```
97
100
98
101
## Caveats
99
102
100
-
During server-side rendering, `$page.state` is always an empty object. The same is true for the first page the user lands on — if the user reloads the page (or returns from another document), state will _not_ be applied until they navigate.
103
+
During server-side rendering, `page.state` is always an empty object. The same is true for the first page the user lands on — if the user reloads the page (or returns from another document), state will _not_ be applied until they navigate.
101
104
102
105
Shallow routing is a feature that requires JavaScript to work. Be mindful when using it and try to think of sensible fallback behavior in case JavaScript isn't available.
0 commit comments