Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
a830774
resolve todos
teemingc Mar 6, 2026
04e9d02
remove note
teemingc Mar 6, 2026
827d2cf
remove legacy notices
teemingc Mar 6, 2026
ea9776c
update
teemingc Mar 6, 2026
0302993
more changesets
teemingc Mar 6, 2026
9d551b7
generate types
teemingc Mar 6, 2026
51c6f4e
format
teemingc Mar 6, 2026
7051187
changeset
teemingc Mar 6, 2026
9e67293
changeset
teemingc Mar 6, 2026
586a565
changeset
teemingc Mar 6, 2026
d41d8a4
fix tests
teemingc Mar 6, 2026
86f5469
remove so they error in ts
teemingc Mar 6, 2026
4802e6e
Merge branch 'version-3' into remove-stores
teemingc Mar 6, 2026
5771abf
fix
teemingc Mar 6, 2026
2c94eaf
forgot
teemingc Mar 6, 2026
e8a3607
maybe this?
teemingc Mar 6, 2026
874e323
still need one tick
teemingc Mar 6, 2026
14b31eb
fix lint
teemingc Mar 6, 2026
0761306
fix root.svelte
teemingc Mar 6, 2026
0a23144
fix announcer
teemingc Mar 6, 2026
c0a09c9
remove unused test
teemingc Mar 6, 2026
d6a1968
restore urls
teemingc Mar 6, 2026
f137ccd
fix base tests
teemingc Mar 6, 2026
c58e850
Merge branch 'main' into remove-stores
teemingc Mar 6, 2026
60b7880
Merge branch 'version-3' into remove-stores
teemingc Mar 6, 2026
204bf2b
comment out deprecate util
teemingc Mar 6, 2026
30b348b
un function
teemingc Mar 6, 2026
091c3d3
fix
teemingc Mar 6, 2026
37757e8
fix test
teemingc Mar 6, 2026
8cd5e90
revert prerendering test app changes
teemingc Mar 7, 2026
fedb71a
split into another PR
teemingc Mar 7, 2026
a8e16c3
split base removal into separate pr
teemingc Mar 7, 2026
84e3081
Merge branch 'version-3' into remove-stores
teemingc Mar 7, 2026
74b4fed
regenerate types
teemingc Mar 7, 2026
65e9724
split
teemingc Mar 7, 2026
8f789f2
remove references in docs
teemingc Mar 7, 2026
457d75d
revert
teemingc Mar 7, 2026
7a3a7d2
revert
teemingc Mar 7, 2026
ff7ae44
split into separate pr
teemingc Mar 7, 2026
26f9ff7
split into separate pr
teemingc Mar 7, 2026
79e6cca
Merge branch 'version-3' into remove-stores
teemingc Mar 9, 2026
096b8b4
split into separate pr
teemingc Mar 9, 2026
49ab52f
split into separate pr
teemingc Mar 9, 2026
c969820
split into separate pr
teemingc Mar 9, 2026
adbb991
keep async
teemingc Mar 9, 2026
c30c850
revert
teemingc Mar 9, 2026
cacf9e4
Merge branch 'version-3' into remove-stores
teemingc Mar 11, 2026
b9eebe0
Merge branch 'version-3' into remove-stores
teemingc Mar 12, 2026
b24e363
split into separate pr
teemingc Mar 12, 2026
4f3ca9c
split
teemingc Mar 12, 2026
20eee63
splittt
teemingc Mar 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/quick-badgers-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': major
---

breaking: remove `$app/stores`
3 changes: 0 additions & 3 deletions documentation/docs/20-core-concepts/10-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,6 @@ If an error occurs during `load`, SvelteKit will render a default error page. Yo
<h1>{page.status}: {page.error.message}</h1>
```

> [!LEGACY]
> `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$app/stores` instead.

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.

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).
Expand Down
4 changes: 0 additions & 4 deletions documentation/docs/20-core-concepts/20-load.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,6 @@ In some cases, we might need the opposite — a parent layout might need to acce

Type information for `page.data` is provided by `App.PageData`.

> [!LEGACY]
> `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$app/stores` instead.
> It provides a `page` store with the same interface that you can subscribe to, e.g. `$page.data.title`.

## Universal vs server

As we've seen, there are two types of `load` function:
Expand Down
2 changes: 1 addition & 1 deletion documentation/docs/20-core-concepts/50-state-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ If you're not using SSR, then there's no risk of accidentally exposing one user'

## Using state and stores with context

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:
You might wonder how we're able to use `page.data` and other [app state]($app-state) 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:

```svelte
<!--- file: src/routes/+layout.svelte --->
Expand Down
3 changes: 0 additions & 3 deletions documentation/docs/30-advanced/25-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ This throws an exception that SvelteKit catches, causing it to set the response
<h1>{page.error.message}</h1>
```

> [!LEGACY]
> `$app/state` was added in SvelteKit 2.12. If you're using an earlier version or are using Svelte 4, use `$app/stores` instead.

You can add extra properties to the error object if needed...

```js
Expand Down
3 changes: 0 additions & 3 deletions documentation/docs/30-advanced/67-shallow-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ The second argument is the new page state, which can be accessed via the [page o

To set page state without creating a new history entry, use `replaceState` instead of `pushState`.

> [!LEGACY]
> `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.

## Loading data for a route

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.
Expand Down
3 changes: 0 additions & 3 deletions documentation/docs/98-reference/20-$app-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,4 @@ title: $app/state

SvelteKit makes three read-only state objects available via the `$app/state` module — `page`, `navigating` and `updated`.

> [!NOTE]
> This module was added in 2.12. If you're using an earlier version of SvelteKit, use [`$app/stores`]($app-stores) instead.

> MODULE: $app/state
4 changes: 1 addition & 3 deletions documentation/docs/98-reference/20-$app-stores.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@
title: $app/stores
---

This module contains store-based equivalents of the exports from [`$app/state`]($app-state). If you're using SvelteKit 2.12 or later, use that module instead.

> MODULE: $app/stores
This module contained store-based equivalents of the exports from [`$app/state`]($app-state) but was removed in 3.0.
3 changes: 1 addition & 2 deletions packages/kit/scripts/generate-dts.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ await createBundle({
'$app/navigation': 'src/runtime/app/navigation.js',
'$app/paths': 'src/runtime/app/paths/public.d.ts',
'$app/server': 'src/runtime/app/server/index.js',
'$app/state': 'src/runtime/app/state/index.js',
'$app/stores': 'src/runtime/app/stores.js'
'$app/state': 'src/runtime/app/state/index.js'
},
include: ['src']
});
Expand Down
40 changes: 12 additions & 28 deletions packages/kit/src/core/sync/write_root.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,45 +81,29 @@ export function write_root(manifest_data, config, output) {
<!-- This file is generated by @sveltejs/kit — do not edit it! -->
<svelte:options runes={true} />
<script>
import { setContext, onMount, tick } from 'svelte';
import { browser } from '$app/environment';
import { tick } from 'svelte';

// stores
let { stores, page, constructors, components = [], form, ${use_boundaries ? 'errors = [], error, ' : ''}${levels
let { page, constructors, components = [], form, ${use_boundaries ? 'errors = [], error, ' : ''}${levels
.map((l) => `data_${l} = null`)
.join(', ')} } = $props();
${use_boundaries ? `let data = $derived({${levels.map((l) => `'${l}': data_${l}`).join(', ')}})` : ''}

if (browser) {
$effect.pre(() => stores.page.set(page));
} else {
// svelte-ignore state_referenced_locally
setContext('__svelte__', stores);
// svelte-ignore state_referenced_locally
stores.page.set(page);
}

$effect(() => {
stores;page;constructors;components;form;${use_boundaries ? 'errors;error;' : ''}${levels.map((l) => `data_${l}`).join(';')};
stores.page.notify();
});

let mounted = $state(false);
let navigated = $state(false);
let title = $state(null);

onMount(() => {
const unsubscribe = stores.page.subscribe(() => {
if (mounted) {
navigated = true;
tick().then(() => {
title = document.title || 'untitled page';
});
}
});
let initialised = false;

$effect(() => {
page;
if (initialised) {
navigated = true;
tick().then(() => {
title = document.title || 'untitled page';
});
}
mounted = true;
return unsubscribe;
initialised = true;
Copy link
Copy Markdown
Member Author

@teemingc teemingc Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a choice of doing if(untrack(() => mounted)) or having this non-reactive flag so that we only announce routes after the first time page is updated. Seemed cheaper to not import untrack

});

const Pyramid_${max_depth} = $derived(constructors[${max_depth}]);
Expand Down
15 changes: 0 additions & 15 deletions packages/kit/src/exports/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,6 @@ import { text_encoder } from '../runtime/utils.js';

export { VERSION } from '../version.js';

// TODO 3.0: remove these types as they are not used anymore (we can't remove them yet because that would be a breaking change)
/**
* @template {number} TNumber
* @template {any[]} [TArray=[]]
* @typedef {TNumber extends TArray['length'] ? TArray[number] : LessThan<TNumber, [...TArray, TArray['length']]>} LessThan
*/

/**
* @template {number} TStart
* @template {number} TEnd
* @typedef {Exclude<TEnd | LessThan<TEnd>, LessThan<TStart>>} NumericRange
*/

// Keep the status codes as `number` because restricting to certain numbers makes it unnecessarily hard to use compared to the benefits
// (we have runtime errors already to check for invalid codes). Also see https://github.com/sveltejs/kit/issues/11780

Expand Down Expand Up @@ -137,8 +124,6 @@ export function isRedirect(e) {
* @deprecated use `Response.json`
*/
export function json(data, init) {
// TODO deprecate this in favour of `Response.json` when it's
// more widely supported
const body = JSON.stringify(data);

// we can't just do `text(JSON.stringify(data), init)` because
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/exports/public.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1367,7 +1367,7 @@ export type AfterNavigate = (Navigation | NavigationEnter) & {
};

/**
* The shape of the [`page`](https://svelte.dev/docs/kit/$app-state#page) reactive object and the [`$page`](https://svelte.dev/docs/kit/$app-stores) store.
* The shape of the [`page`](https://svelte.dev/docs/kit/$app-state#page) reactive object.
*/
export interface Page<
Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>,
Expand Down
3 changes: 1 addition & 2 deletions packages/kit/src/runtime/app/state/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
navigating as _navigating,
updated as _updated
} from '../../client/state.svelte.js';
import { stores } from '../../client/client.js';

export const page = {
get data() {
Expand Down Expand Up @@ -57,5 +56,5 @@ export const updated = {
get current() {
return _updated.current;
},
check: stores.updated.check
check: _updated.check
};
101 changes: 0 additions & 101 deletions packages/kit/src/runtime/app/stores.js

This file was deleted.

Loading
Loading