Skip to content

Commit 3d88ae3

Browse files
authored
fix: change server-side route resolution endpoint (#13461)
Instead of doing route resolution requests through `_app/route/...`, do it through `<pathname>/__route.js`: - more consistent with what we do for `/__data.json` requests already - avoids problems with cookies: If you set a cookie on `/foo`, we would need to add it to `_app/route/foo` aswell, if we didn't change this
1 parent 9719e1e commit 3d88ae3

File tree

9 files changed

+26
-25
lines changed

9 files changed

+26
-25
lines changed

.changeset/modern-fishes-chew.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@sveltejs/adapter-vercel': patch
3+
'@sveltejs/kit': patch
4+
---
5+
6+
fix: change server-side route resolution endpoint

packages/adapter-vercel/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ const plugin = function (defaults = {}) {
405405
);
406406

407407
static_config.routes.push({
408-
src: `${builder.config.kit.paths.base}/${builder.config.kit.appDir}/route(\\.js|/.*)`,
408+
src: `${builder.config.kit.paths.base}/(|.+/)__route\\.js`,
409409
dest: `${builder.config.kit.paths.base}/${builder.config.kit.appDir}/route`
410410
});
411411
}

packages/kit/src/runtime/client/client.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM, validate_depends } from '../sh
3939
import { get_message, get_status } from '../../utils/error.js';
4040
import { writable } from 'svelte/store';
4141
import { page, update, navigating } from './state.svelte.js';
42-
import { add_data_suffix, add_resolution_prefix } from '../pathname.js';
42+
import { add_data_suffix, add_resolution_suffix } from '../pathname.js';
4343

4444
const ICON_REL_ATTRIBUTES = new Set(['icon', 'shortcut icon', 'apple-touch-icon']);
4545

@@ -1265,7 +1265,7 @@ async function get_navigation_intent(url, invalidating) {
12651265
/** @type {{ route?: import('types').CSRRouteServer, params: Record<string, string>}} */
12661266
const { route, params } = await import(
12671267
/* @vite-ignore */
1268-
add_resolution_prefix(url.pathname)
1268+
add_resolution_suffix(url.pathname)
12691269
);
12701270

12711271
if (!route) return;

packages/kit/src/runtime/pathname.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { base, app_dir } from '__sveltekit/paths';
2-
31
const DATA_SUFFIX = '/__data.json';
42
const HTML_DATA_SUFFIX = '.html__data.json';
53

@@ -23,32 +21,29 @@ export function strip_data_suffix(pathname) {
2321
return pathname.slice(0, -DATA_SUFFIX.length);
2422
}
2523

26-
const ROUTE_PREFIX = `${base}/${app_dir}/route`;
24+
const ROUTE_SUFFIX = '/__route.js';
2725

2826
/**
2927
* @param {string} pathname
3028
* @returns {boolean}
3129
*/
32-
export function has_resolution_prefix(pathname) {
33-
return pathname === `${ROUTE_PREFIX}.js` || pathname.startsWith(`${ROUTE_PREFIX}/`);
30+
export function has_resolution_suffix(pathname) {
31+
return pathname.endsWith(ROUTE_SUFFIX);
3432
}
3533

3634
/**
3735
* Convert a regular URL to a route to send to SvelteKit's server-side route resolution endpoint
3836
* @param {string} pathname
3937
* @returns {string}
4038
*/
41-
export function add_resolution_prefix(pathname) {
42-
let normalized = pathname.slice(base.length);
43-
if (normalized.endsWith('/')) normalized = normalized.slice(0, -1);
44-
45-
return `${ROUTE_PREFIX}${normalized}.js`;
39+
export function add_resolution_suffix(pathname) {
40+
return pathname.replace(/\/$/, '') + ROUTE_SUFFIX;
4641
}
4742

4843
/**
4944
* @param {string} pathname
5045
* @returns {string}
5146
*/
52-
export function strip_resolution_prefix(pathname) {
53-
return base + (pathname.slice(ROUTE_PREFIX.length, -3) || '/');
47+
export function strip_resolution_suffix(pathname) {
48+
return pathname.slice(0, -ROUTE_SUFFIX.length);
5449
}

packages/kit/src/runtime/server/page/render.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { create_async_iterator } from '../../../utils/streaming.js';
1414
import { SVELTE_KIT_ASSETS } from '../../../constants.js';
1515
import { SCHEME } from '../../../utils/url.js';
1616
import { create_server_routing_response, generate_route_object } from './server_routing.js';
17-
import { add_resolution_prefix } from '../../pathname.js';
17+
import { add_resolution_suffix } from '../../pathname.js';
1818

1919
// TODO rename this function/module
2020

@@ -321,9 +321,9 @@ export async function render_response({
321321
}
322322
}
323323

324-
// prerender a `/_app/route/path/to/page.js` module
324+
// prerender a `/path/to/page/__route.js` module
325325
if (manifest._.client.routes && state.prerendering && !state.prerendering.fallback) {
326-
const pathname = add_resolution_prefix(event.url.pathname);
326+
const pathname = add_resolution_suffix(event.url.pathname);
327327

328328
state.prerendering.dependencies.set(
329329
pathname,

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ import { resolve_route } from './page/server_routing.js';
3030
import { validateHeaders } from './validate-headers.js';
3131
import {
3232
has_data_suffix,
33-
has_resolution_prefix,
33+
has_resolution_suffix,
3434
strip_data_suffix,
35-
strip_resolution_prefix
35+
strip_resolution_suffix
3636
} from '../pathname.js';
3737

3838
/* global __SVELTEKIT_ADAPTER_NAME__ */
@@ -94,11 +94,11 @@ export async function respond(request, options, manifest, state) {
9494
* If the request is for a route resolution, first modify the URL, then continue as normal
9595
* for path resolution, then return the route object as a JS file.
9696
*/
97-
const is_route_resolution_request = has_resolution_prefix(url.pathname);
97+
const is_route_resolution_request = has_resolution_suffix(url.pathname);
9898
const is_data_request = has_data_suffix(url.pathname);
9999

100100
if (is_route_resolution_request) {
101-
url.pathname = strip_resolution_prefix(url.pathname);
101+
url.pathname = strip_resolution_suffix(url.pathname);
102102
} else if (is_data_request) {
103103
url.pathname =
104104
strip_data_suffix(url.pathname) +

packages/kit/src/types/internal.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export type CSRRoute = {
121121
};
122122

123123
/**
124-
* Definition of a client side route as transported via `_app/route/...` when using server-side route resolution.
124+
* Definition of a client side route as transported via `<pathname>/__route.js` when using server-side route resolution.
125125
*/
126126
export type CSRRouteServer = {
127127
id: string;

packages/kit/test/apps/basics/test/client.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ test.describe('Load', () => {
235235

236236
// 4. We expect the same data and no new request (except a navigation request in case of server-side route resolution) because it was cached.
237237
expect(await page.textContent('h2')).toBe('a / b');
238-
expect(requests.filter((r) => !r.includes('_app/route'))).toEqual([]);
238+
expect(requests.filter((r) => !r.includes('/__route.js'))).toEqual([]);
239239
});
240240

241241
test('permits 3rd party patching of fetch in universal load functions', async ({ page }) => {

packages/kit/test/apps/basics/test/cross-platform/client.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ test.describe('Routing', () => {
864864
await page.locator('button').click();
865865

866866
// Filter out server-side route resolution request
867-
expect(requests.filter((r) => !r.includes('_app/route'))).toEqual([]);
867+
expect(requests.filter((r) => !r.includes('__route.js'))).toEqual([]);
868868
expect(await page.textContent('h1')).toBe('updated');
869869
expect(await page.textContent('h2')).toBe('form');
870870
expect(await page.textContent('h3')).toBe('bar');

0 commit comments

Comments
 (0)