diff --git a/.changeset/nasty-lemons-provide.md b/.changeset/nasty-lemons-provide.md
new file mode 100644
index 000000000000..66e7d1f02a46
--- /dev/null
+++ b/.changeset/nasty-lemons-provide.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+[breaking] remove fallthrough routes
diff --git a/documentation/docs/01-routing.md b/documentation/docs/01-routing.md
index 28c1c90a3fcd..979fde396046 100644
--- a/documentation/docs/01-routing.md
+++ b/documentation/docs/01-routing.md
@@ -323,11 +323,10 @@ A route can have multiple dynamic parameters, for example `src/routes/[category]
It's possible for multiple routes to match a given path. For example each of these routes would match `/foo-abc`:
```bash
+src/routes/[...catchall].svelte
src/routes/[a].js
src/routes/[b].svelte
-src/routes/[c].svelte
-src/routes/[...catchall].svelte
-src/routes/foo-[bar].svelte
+src/routes/foo-[c].svelte
```
SvelteKit needs to know which route is being requested. To do so, it sorts them according to the following rules...
@@ -340,48 +339,8 @@ SvelteKit needs to know which route is being requested. To do so, it sorts them
...resulting in this ordering, meaning that `/foo-abc` will invoke `src/routes/foo-[bar].svelte` rather than a less specific route:
```bash
-src/routes/foo-[bar].svelte
+src/routes/foo-[c].svelte
src/routes/[a].js
src/routes/[b].svelte
-src/routes/[c].svelte
src/routes/[...catchall].svelte
```
-
-#### Fallthrough routes
-
-In rare cases, the ordering above might not be what you want for a given path. For example, perhaps `/foo-abc` should resolve to `src/routes/foo-[bar].svelte`, but `/foo-def` should resolve to `src/routes/[b].svelte`.
-
-Higher priority routes can _fall through_ to lower priority routes by returning `{ fallthrough: true }`, either from `load` (for pages) or a request handler (for endpoints):
-
-```svelte
-/// file: src/routes/foo-[bar].svelte
-
-```
-
-```js
-/// file: src/routes/[a].js
-
-// @filename: [a].d.ts
-import type { RequestHandler as GenericRequestHandler } from '@sveltejs/kit';
-export type RequestHandler
= GenericRequestHandler<{ a: string }, Body>;
-
-// @filename: index.js
-// @errors: 2366
-// ---cut---
-/** @type {import('./[a]').RequestHandler} */
-export function get({ params }) {
- if (params.a === 'foo-def') {
- return { fallthrough: true };
- }
-
- // ...
-}
-```
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index 0c9701d98c82..65a3ca39bbc1 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -177,7 +177,7 @@ export function create_client({ target, session, base, trailing_slash }) {
const intent = get_navigation_intent(url);
- load_cache.promise = get_navigation_result(intent, false);
+ load_cache.promise = load_route(intent, false);
load_cache.id = intent.id;
return load_cache.promise;
@@ -191,7 +191,7 @@ export function create_client({ target, session, base, trailing_slash }) {
*/
async function update(intent, redirect_chain, no_cache, opts) {
const current_token = (token = {});
- let navigation_result = await get_navigation_result(intent, no_cache);
+ let navigation_result = await load_route(intent, no_cache);
if (!navigation_result && intent.url.pathname === location.pathname) {
// this could happen in SPA fallback mode if the user navigated to
@@ -341,36 +341,6 @@ export function create_client({ target, session, base, trailing_slash }) {
}
}
- /**
- * @param {import('./types').NavigationIntent} intent
- * @param {boolean} no_cache
- */
- async function get_navigation_result(intent, no_cache) {
- if (load_cache.id === intent.id && load_cache.promise) {
- return load_cache.promise;
- }
-
- for (let i = 0; i < intent.routes.length; i += 1) {
- const route = intent.routes[i];
-
- // load code for subsequent routes immediately, if they are as
- // likely to match the current path/query as the current one
- let j = i + 1;
- while (j < intent.routes.length) {
- const next = intent.routes[j];
- if (next[0].toString() === route[0].toString()) {
- next[1].forEach((loader) => loader());
- j += 1;
- } else {
- break;
- }
- }
-
- const result = await load_route(route, intent, no_cache);
- if (result) return result;
- }
- }
-
/**
*
* @param {{
@@ -557,11 +527,16 @@ export function create_client({ target, session, base, trailing_slash }) {
}
/**
- * @param {import('types').CSRRoute} route
* @param {import('./types').NavigationIntent} intent
* @param {boolean} no_cache
*/
- async function load_route(route, { id, url, path, routes }, no_cache) {
+ async function load_route({ id, url, path, route }, no_cache) {
+ if (!route) return;
+
+ if (load_cache.id === id && load_cache.promise) {
+ return load_cache.promise;
+ }
+
if (!no_cache) {
const cached = cache.get(id);
if (cached) return cached;
@@ -625,7 +600,7 @@ export function create_client({ target, session, base, trailing_slash }) {
`${url.pathname}${url.pathname.endsWith('/') ? '' : '/'}__data.json${url.search}`,
{
headers: {
- 'x-sveltekit-load': /** @type {string} */ (shadow_key)
+ 'x-sveltekit-load': 'true'
}
}
);
@@ -641,15 +616,7 @@ export function create_client({ target, session, base, trailing_slash }) {
};
}
- if (res.status === 204) {
- if (route !== routes[routes.length - 1]) {
- // fallthrough
- return;
- }
- props = {};
- } else {
- props = await res.json();
- }
+ props = res.status === 204 ? {} : await res.json();
} else {
status = res.status;
error = new Error('Failed to load data');
@@ -672,9 +639,12 @@ export function create_client({ target, session, base, trailing_slash }) {
}
if (node.loaded) {
+ // TODO remove for 1.0
+ // @ts-expect-error
if (node.loaded.fallthrough) {
- return;
+ throw new Error('fallthrough is no longer supported');
}
+
if (node.loaded.error) {
status = node.loaded.status;
error = node.loaded.error;
@@ -811,6 +781,7 @@ export function create_client({ target, session, base, trailing_slash }) {
/** @param {URL} url */
function owns(url) {
+ // TODO now that we've got rid of fallthrough, check against routes immediately
return url.origin === location.origin && url.pathname.startsWith(base);
}
@@ -821,7 +792,7 @@ export function create_client({ target, session, base, trailing_slash }) {
/** @type {import('./types').NavigationIntent} */
const intent = {
id: url.pathname + url.search,
- routes: routes.filter(([pattern]) => pattern.test(path)),
+ route: routes.find(([pattern]) => pattern.test(path)),
url,
path
};
@@ -860,14 +831,14 @@ export function create_client({ target, session, base, trailing_slash }) {
return;
}
- if (!owns(url)) {
+ const pathname = normalize_path(url.pathname, trailing_slash);
+ const normalized = new URL(url.origin + pathname + url.search + url.hash);
+
+ if (!owns(normalized)) {
await native_navigation(url);
}
- const pathname = normalize_path(url.pathname, trailing_slash);
- url = new URL(url.origin + pathname + url.search + url.hash);
-
- const intent = get_navigation_intent(url);
+ const intent = get_navigation_intent(normalized);
update_scroll_positions(current_history_index);
@@ -896,7 +867,7 @@ export function create_client({ target, session, base, trailing_slash }) {
if (navigating_token !== current_navigating_token) return;
if (!navigating) {
- const navigation = { from, to: url };
+ const navigation = { from, to: normalized };
callbacks.after_navigate.forEach((fn) => fn(navigation));
stores.navigating.set(null);
diff --git a/packages/kit/src/runtime/client/types.d.ts b/packages/kit/src/runtime/client/types.d.ts
index 7709e5e4f302..107d10363e80 100644
--- a/packages/kit/src/runtime/client/types.d.ts
+++ b/packages/kit/src/runtime/client/types.d.ts
@@ -38,9 +38,9 @@ export type NavigationIntent = {
*/
path: string;
/**
- * The routes that could satisfy this navigation intent
+ * The route that matches `path`
*/
- routes: CSRRoute[];
+ route: CSRRoute | undefined; // TODO i'm pretty sure we can make this required, and simplify some stuff
/**
* The destination URL
*/
diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js
index 8cea0ea439b0..c99fbcf00bf5 100644
--- a/packages/kit/src/runtime/server/endpoint.js
+++ b/packages/kit/src/runtime/server/endpoint.js
@@ -59,8 +59,10 @@ export async function render_endpoint(event, mod) {
return error(`${preface}: expected an object, got ${typeof response}`);
}
+ // TODO remove for 1.0
+ // @ts-expect-error
if (response.fallthrough) {
- return;
+ throw new Error('fallthrough is no longer supported');
}
const { status = 200, body = {} } = response;
diff --git a/packages/kit/src/runtime/server/index.js b/packages/kit/src/runtime/server/index.js
index a571d1f1ee1b..3634d43145cb 100644
--- a/packages/kit/src/runtime/server/index.js
+++ b/packages/kit/src/runtime/server/index.js
@@ -165,17 +165,7 @@ export async function respond(request, options, state) {
event.url = new URL(event.url.origin + normalized + event.url.search);
}
- // `key` will be set if this request came from a client-side navigation
- // to a page with a matching endpoint
- const key = request.headers.get('x-sveltekit-load');
-
for (const route of options.manifest._.routes) {
- if (key) {
- // client is requesting data for a specific endpoint
- if (route.type !== 'page') continue;
- if (route.key !== key) continue;
- }
-
const match = route.pattern.exec(decoded);
if (!match) continue;
@@ -188,7 +178,7 @@ export async function respond(request, options, state) {
response = await render_endpoint(event, await route.shadow());
// loading data for a client-side transition is a special case
- if (key) {
+ if (request.headers.has('x-sveltekit-load')) {
if (response) {
// since redirects are opaque to the browser, we need to repackage
// 3xx responses as 200s with a custom header
@@ -205,12 +195,8 @@ export async function respond(request, options, state) {
}
}
} else {
- // fallthrough
response = new Response(undefined, {
- status: 204,
- headers: {
- 'content-type': 'application/json'
- }
+ status: 204
});
}
}
@@ -257,6 +243,8 @@ export async function respond(request, options, state) {
return response;
}
+
+ break;
}
// if this request came direct from the user, rather than
diff --git a/packages/kit/src/runtime/server/page/load_node.js b/packages/kit/src/runtime/server/page/load_node.js
index ee01caf65057..7857a66da403 100644
--- a/packages/kit/src/runtime/server/page/load_node.js
+++ b/packages/kit/src/runtime/server/page/load_node.js
@@ -21,7 +21,7 @@ import { coalesce_to_error } from '../../../utils/error.js';
* status?: number;
* error?: Error;
* }} opts
- * @returns {Promise} undefined for fallthrough
+ * @returns {Promise}
*/
export async function load_node({
event,
@@ -50,7 +50,7 @@ export async function load_node({
*/
let set_cookie_headers = [];
- /** @type {import('types').Either} */
+ /** @type {import('types').LoadOutput} */
let loaded;
/** @type {import('types').ShadowData} */
@@ -63,8 +63,6 @@ export async function load_node({
)
: {};
- if (shadow.fallthrough) return;
-
if (shadow.cookies) {
set_cookie_headers.push(...shadow.cookies);
}
@@ -325,8 +323,15 @@ export async function load_node({
loaded = await module.load.call(null, load_input);
if (!loaded) {
+ // TODO do we still want to enforce this now that there's no fallthrough?
throw new Error(`load function must return a value${options.dev ? ` (${node.entry})` : ''}`);
}
+
+ // TODO remove for 1.0
+ // @ts-expect-error
+ if (loaded.fallthrough) {
+ throw new Error('fallthrough is no longer supported');
+ }
} else if (shadow.body) {
loaded = {
props: shadow.body
@@ -335,10 +340,6 @@ export async function load_node({
loaded = {};
}
- if (loaded.fallthrough && !is_error) {
- return;
- }
-
// generate __data.json files when prerendering
if (shadow.body && state.prerender) {
const pathname = `${event.url.pathname.replace(/\/$/, '')}/__data.json`;
@@ -401,7 +402,11 @@ async function load_shadow_data(route, event, options, prerender) {
if (!is_get) {
const result = await handler(event);
- if (result.fallthrough) return result;
+ // TODO remove for 1.0
+ // @ts-expect-error
+ if (result.fallthrough) {
+ throw new Error('fallthrough is no longer supported');
+ }
const { status, headers, body } = validate_shadow_output(result);
data.status = status;
@@ -426,7 +431,11 @@ async function load_shadow_data(route, event, options, prerender) {
if (get) {
const result = await get(event);
- if (result.fallthrough) return result;
+ // TODO remove for 1.0
+ // @ts-expect-error
+ if (result.fallthrough) {
+ throw new Error('fallthrough is no longer supported');
+ }
const { status, headers, body } = validate_shadow_output(result);
add_cookies(/** @type {string[]} */ (data.cookies), headers);
diff --git a/packages/kit/test/apps/basics/src/routes/endpoint-output/empty.js b/packages/kit/test/apps/basics/src/routes/endpoint-output/empty.js
index e396a880ac27..75f45f44c15e 100644
--- a/packages/kit/test/apps/basics/src/routes/endpoint-output/empty.js
+++ b/packages/kit/test/apps/basics/src/routes/endpoint-output/empty.js
@@ -2,8 +2,3 @@
export function get() {
return {};
}
-
-/** @type {import('@sveltejs/kit').RequestHandler} */
-export function del() {
- return { fallthrough: true };
-}
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[animal].json.js b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[animal].json.js
deleted file mode 100644
index 6a38766dbf37..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[animal].json.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const animals = new Set(['antelope', 'barracuda', 'camel', 'dingo', 'elephant']);
-
-/** @type {import("@sveltejs/kit").RequestHandler} */
-export function get({ params }) {
- if (animals.has(params.animal)) {
- return {
- body: { type: 'animal' }
- };
- }
- return { fallthrough: true };
-}
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[animal].svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[animal].svelte
deleted file mode 100644
index 8cbc2adf6990..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[animal].svelte
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-{animal} is an animal
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[mineral].json.js b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[mineral].json.js
deleted file mode 100644
index b214adea3672..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[mineral].json.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const minerals = new Set(['aluminium', 'borax', 'chromium', 'diamond', 'edenite']);
-
-/** @type {import("@sveltejs/kit").RequestHandler} */
-export function get({ params }) {
- if (minerals.has(params.mineral)) {
- return {
- body: { type: 'mineral' }
- };
- }
- return { fallthrough: true };
-}
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[mineral].svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[mineral].svelte
deleted file mode 100644
index 29e2affd9ee1..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[mineral].svelte
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-{mineral} is a mineral
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[vegetable].json.js b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[vegetable].json.js
deleted file mode 100644
index 03e967133c15..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[vegetable].json.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const vegetables = new Set(['asparagus', 'broccoli', 'carrot', 'daikon', 'endive']);
-
-/** @type {import("@sveltejs/kit").RequestHandler} */
-export function get({ params }) {
- if (vegetables.has(params.vegetable)) {
- return {
- body: { type: 'vegetable' }
- };
- }
- return { fallthrough: true };
-}
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[vegetable].svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[vegetable].svelte
deleted file mode 100644
index 8182e2187a38..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/[vegetable].svelte
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-{vegetable} is a vegetable
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/__layout.svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/__layout.svelte
deleted file mode 100644
index 11fe7e83e199..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-advanced/__layout.svelte
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-aluminium
-broccoli
-camel
-
-potato
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[foo]/__layout.svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[foo]/__layout.svelte
deleted file mode 100644
index 7d5da461c75a..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[foo]/__layout.svelte
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[foo]/index.svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[foo]/index.svelte
deleted file mode 100644
index 9272a8854586..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[foo]/index.svelte
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-foo is {$page.params.foo}
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[xyz]/__layout.svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[xyz]/__layout.svelte
deleted file mode 100644
index 977ae9b680ba..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[xyz]/__layout.svelte
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[xyz]/index.svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[xyz]/index.svelte
deleted file mode 100644
index dbdf18b80545..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/[xyz]/index.svelte
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-xyz is {$page.params.xyz}
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/__layout.svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/__layout.svelte
deleted file mode 100644
index 6efc36c2dcfe..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-layout/__layout.svelte
+++ /dev/null
@@ -1,5 +0,0 @@
-okay
-ok
-notok
-
-
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-simple/[legal].svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-simple/[legal].svelte
deleted file mode 100644
index 8cfadc579533..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-simple/[legal].svelte
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-Legal
diff --git a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-simple/[page].svelte b/packages/kit/test/apps/basics/src/routes/routing/fallthrough-simple/[page].svelte
deleted file mode 100644
index a3a6b8392d2e..000000000000
--- a/packages/kit/test/apps/basics/src/routes/routing/fallthrough-simple/[page].svelte
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-Page
diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[a].js b/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[a].js
deleted file mode 100644
index 458e9f018f74..000000000000
--- a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[a].js
+++ /dev/null
@@ -1,15 +0,0 @@
-/** @type {import('./[a]').RequestHandler} */
-export async function get({ params }) {
- const param = params.a;
-
- if (param !== 'a') {
- return {
- fallthrough: true
- };
- }
-
- return {
- status: 200,
- body: { param }
- };
-}
diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[a].svelte b/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[a].svelte
deleted file mode 100644
index 1d367966bb1e..000000000000
--- a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[a].svelte
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-a-{param}
diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[b].js b/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[b].js
deleted file mode 100644
index a7712b014dd3..000000000000
--- a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[b].js
+++ /dev/null
@@ -1,15 +0,0 @@
-/** @type {import('./[b]').RequestHandler} */
-export async function get({ params }) {
- const param = params.b;
-
- if (param !== 'b') {
- return {
- fallthrough: true
- };
- }
-
- return {
- status: 200,
- body: { param }
- };
-}
diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[b].svelte b/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[b].svelte
deleted file mode 100644
index d216e0cbff2f..000000000000
--- a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[b].svelte
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-b-{param}
diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[c].svelte b/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[c].svelte
deleted file mode 100644
index 53379894746e..000000000000
--- a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/[c].svelte
+++ /dev/null
@@ -1 +0,0 @@
-c
diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/index.svelte b/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/index.svelte
deleted file mode 100644
index 8e3b7ad45318..000000000000
--- a/packages/kit/test/apps/basics/src/routes/shadowed/fallthrough/index.svelte
+++ /dev/null
@@ -1,3 +0,0 @@
-fallthrough to shadow a
-fallthrough to shadow b
-fallthrough to no shadow c
diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js
index a3b9401317cc..158a49c05bb5 100644
--- a/packages/kit/test/apps/basics/test/test.js
+++ b/packages/kit/test/apps/basics/test/test.js
@@ -505,18 +505,6 @@ test.describe.parallel('Shadowed pages', () => {
expect(await page.textContent('h1')).toBe('slug: bar');
});
- test('Shadow fallthrough to shadowed page', async ({ page, clicknav }) => {
- await page.goto('/shadowed/fallthrough');
- await clicknav('[href="/shadowed/fallthrough/b"]');
- expect(await page.textContent('h2')).toBe('b-b');
- });
-
- test('Shadow fallthrough to unshadowed page', async ({ page, clicknav }) => {
- await page.goto('/shadowed/fallthrough');
- await clicknav('[href="/shadowed/fallthrough/c"]');
- expect(await page.textContent('h2')).toBe('c');
- });
-
test('Shadow redirect', async ({ page, clicknav }) => {
await page.goto('/shadowed/redirect');
await clicknav('[href="/shadowed/redirect/a"]');
@@ -550,11 +538,6 @@ test.describe.parallel('Endpoints', () => {
}
});
- test('not ok on void endpoint', async ({ request }) => {
- const response = await request.delete('/endpoint-output/empty');
- expect(response.ok()).toBe(false);
- });
-
test('200 status on empty endpoint', async ({ request }) => {
const response = await request.get('/endpoint-output/empty');
expect(/** @type {import('@playwright/test').APIResponse} */ (response).status()).toBe(200);
@@ -2032,33 +2015,6 @@ test.describe.parallel('Routing', () => {
}
});
- test('fallthrough', async ({ page }) => {
- await page.goto('/routing/fallthrough-simple/invalid');
- expect(await page.textContent('h1')).toBe('Page');
- });
-
- test('dynamic fallthrough of pages and endpoints', async ({ page, clicknav }) => {
- await page.goto('/routing/fallthrough-advanced/borax');
- expect(await page.textContent('h1')).toBe('borax is a mineral');
-
- await clicknav('[href="/routing/fallthrough-advanced/camel"]');
- expect(await page.textContent('h1')).toBe('camel is an animal');
-
- await clicknav('[href="/routing/fallthrough-advanced/potato"]');
- expect(await page.textContent('h1')).toBe('404');
- });
-
- test('dynamic fallthrough of layout', async ({ page, clicknav }) => {
- await page.goto('/routing/fallthrough-layout/okay');
- expect(await page.textContent('h1')).toBe('foo is okay');
-
- await clicknav('[href="/routing/fallthrough-layout/ok"]');
- expect(await page.textContent('h1')).toBe('xyz is ok');
-
- await clicknav('[href="/routing/fallthrough-layout/notok"]');
- expect(await page.textContent('h1')).toBe('404');
- });
-
test('last parameter in a segment wins in cases of ambiguity', async ({ page, clicknav }) => {
await page.goto('/routing/split-params');
await clicknav('[href="/routing/split-params/x-y-z"]');
diff --git a/packages/kit/test/typings/endpoint.test.ts b/packages/kit/test/typings/endpoint.test.ts
index 9f5af8ec3fc5..5fcb44ce8e31 100644
--- a/packages/kit/test/typings/endpoint.test.ts
+++ b/packages/kit/test/typings/endpoint.test.ts
@@ -105,18 +105,3 @@ export const error_nested_instances: RequestHandler = () => {
body: { typed: new Uint8Array() }
};
};
-
-// @ts-expect-error - fallthrough must be isolated
-export const error_fallthrough_not_isolated: RequestHandler = () => {
- return {
- body: {},
- fallthrough: true
- };
-};
-
-// @ts-expect-error - fallthrough must be of value `true`
-export const error_fallthrough_not_true: RequestHandler = () => {
- return {
- fallthrough: null
- };
-};
diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts
index cc289bf32c7e..03f18c1b7ab9 100644
--- a/packages/kit/types/index.d.ts
+++ b/packages/kit/types/index.d.ts
@@ -9,7 +9,6 @@ import {
CspDirectives,
Either,
ErrorLoadInput,
- Fallthrough,
JSONValue,
LoadInput,
LoadOutput,
@@ -194,9 +193,7 @@ export interface Load<
InputProps extends Record = Record,
OutputProps extends Record = InputProps
> {
- (input: LoadInput): MaybePromise<
- Either>
- >;
+ (input: LoadInput): MaybePromise>;
}
export interface Navigation {
@@ -228,16 +225,11 @@ export interface RequestHandler<
(event: RequestEvent): RequestHandlerOutput