From 3d88ae33fc14b08a1d48c2cb7315739c8cfcd9fd Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Thu, 13 Feb 2025 17:26:27 +0100 Subject: [PATCH] fix: change server-side route resolution endpoint (#13461) Instead of doing route resolution requests through `_app/route/...`, do it through `/__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 --- .changeset/modern-fishes-chew.md | 6 ++++++ packages/adapter-vercel/index.js | 2 +- packages/kit/src/runtime/client/client.js | 4 ++-- packages/kit/src/runtime/pathname.js | 19 +++++++------------ .../kit/src/runtime/server/page/render.js | 6 +++--- packages/kit/src/runtime/server/respond.js | 8 ++++---- packages/kit/src/types/internal.d.ts | 2 +- .../kit/test/apps/basics/test/client.test.js | 2 +- .../basics/test/cross-platform/client.test.js | 2 +- 9 files changed, 26 insertions(+), 25 deletions(-) create mode 100644 .changeset/modern-fishes-chew.md diff --git a/.changeset/modern-fishes-chew.md b/.changeset/modern-fishes-chew.md new file mode 100644 index 000000000000..35af0ccfefc1 --- /dev/null +++ b/.changeset/modern-fishes-chew.md @@ -0,0 +1,6 @@ +--- +'@sveltejs/adapter-vercel': patch +'@sveltejs/kit': patch +--- + +fix: change server-side route resolution endpoint diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js index 18a008816f70..d87f6946ed79 100644 --- a/packages/adapter-vercel/index.js +++ b/packages/adapter-vercel/index.js @@ -405,7 +405,7 @@ const plugin = function (defaults = {}) { ); static_config.routes.push({ - src: `${builder.config.kit.paths.base}/${builder.config.kit.appDir}/route(\\.js|/.*)`, + src: `${builder.config.kit.paths.base}/(|.+/)__route\\.js`, dest: `${builder.config.kit.paths.base}/${builder.config.kit.appDir}/route` }); } diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index 63ed3c910476..def673a01d20 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -39,7 +39,7 @@ import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM, validate_depends } from '../sh import { get_message, get_status } from '../../utils/error.js'; import { writable } from 'svelte/store'; import { page, update, navigating } from './state.svelte.js'; -import { add_data_suffix, add_resolution_prefix } from '../pathname.js'; +import { add_data_suffix, add_resolution_suffix } from '../pathname.js'; const ICON_REL_ATTRIBUTES = new Set(['icon', 'shortcut icon', 'apple-touch-icon']); @@ -1265,7 +1265,7 @@ async function get_navigation_intent(url, invalidating) { /** @type {{ route?: import('types').CSRRouteServer, params: Record}} */ const { route, params } = await import( /* @vite-ignore */ - add_resolution_prefix(url.pathname) + add_resolution_suffix(url.pathname) ); if (!route) return; diff --git a/packages/kit/src/runtime/pathname.js b/packages/kit/src/runtime/pathname.js index f9a2d3b23d2f..7c2f80ca4642 100644 --- a/packages/kit/src/runtime/pathname.js +++ b/packages/kit/src/runtime/pathname.js @@ -1,5 +1,3 @@ -import { base, app_dir } from '__sveltekit/paths'; - const DATA_SUFFIX = '/__data.json'; const HTML_DATA_SUFFIX = '.html__data.json'; @@ -23,14 +21,14 @@ export function strip_data_suffix(pathname) { return pathname.slice(0, -DATA_SUFFIX.length); } -const ROUTE_PREFIX = `${base}/${app_dir}/route`; +const ROUTE_SUFFIX = '/__route.js'; /** * @param {string} pathname * @returns {boolean} */ -export function has_resolution_prefix(pathname) { - return pathname === `${ROUTE_PREFIX}.js` || pathname.startsWith(`${ROUTE_PREFIX}/`); +export function has_resolution_suffix(pathname) { + return pathname.endsWith(ROUTE_SUFFIX); } /** @@ -38,17 +36,14 @@ export function has_resolution_prefix(pathname) { * @param {string} pathname * @returns {string} */ -export function add_resolution_prefix(pathname) { - let normalized = pathname.slice(base.length); - if (normalized.endsWith('/')) normalized = normalized.slice(0, -1); - - return `${ROUTE_PREFIX}${normalized}.js`; +export function add_resolution_suffix(pathname) { + return pathname.replace(/\/$/, '') + ROUTE_SUFFIX; } /** * @param {string} pathname * @returns {string} */ -export function strip_resolution_prefix(pathname) { - return base + (pathname.slice(ROUTE_PREFIX.length, -3) || '/'); +export function strip_resolution_suffix(pathname) { + return pathname.slice(0, -ROUTE_SUFFIX.length); } diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 3885b9cf986b..ae8ca1bb5e0b 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -14,7 +14,7 @@ import { create_async_iterator } from '../../../utils/streaming.js'; import { SVELTE_KIT_ASSETS } from '../../../constants.js'; import { SCHEME } from '../../../utils/url.js'; import { create_server_routing_response, generate_route_object } from './server_routing.js'; -import { add_resolution_prefix } from '../../pathname.js'; +import { add_resolution_suffix } from '../../pathname.js'; // TODO rename this function/module @@ -321,9 +321,9 @@ export async function render_response({ } } - // prerender a `/_app/route/path/to/page.js` module + // prerender a `/path/to/page/__route.js` module if (manifest._.client.routes && state.prerendering && !state.prerendering.fallback) { - const pathname = add_resolution_prefix(event.url.pathname); + const pathname = add_resolution_suffix(event.url.pathname); state.prerendering.dependencies.set( pathname, diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index 429d523c3715..05b1934d0595 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -30,9 +30,9 @@ import { resolve_route } from './page/server_routing.js'; import { validateHeaders } from './validate-headers.js'; import { has_data_suffix, - has_resolution_prefix, + has_resolution_suffix, strip_data_suffix, - strip_resolution_prefix + strip_resolution_suffix } from '../pathname.js'; /* global __SVELTEKIT_ADAPTER_NAME__ */ @@ -94,11 +94,11 @@ export async function respond(request, options, manifest, state) { * If the request is for a route resolution, first modify the URL, then continue as normal * for path resolution, then return the route object as a JS file. */ - const is_route_resolution_request = has_resolution_prefix(url.pathname); + const is_route_resolution_request = has_resolution_suffix(url.pathname); const is_data_request = has_data_suffix(url.pathname); if (is_route_resolution_request) { - url.pathname = strip_resolution_prefix(url.pathname); + url.pathname = strip_resolution_suffix(url.pathname); } else if (is_data_request) { url.pathname = strip_data_suffix(url.pathname) + diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index c5d2609fc006..12a3b5dac4a8 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -121,7 +121,7 @@ export type CSRRoute = { }; /** - * Definition of a client side route as transported via `_app/route/...` when using server-side route resolution. + * Definition of a client side route as transported via `/__route.js` when using server-side route resolution. */ export type CSRRouteServer = { id: string; diff --git a/packages/kit/test/apps/basics/test/client.test.js b/packages/kit/test/apps/basics/test/client.test.js index 72e4973a95d5..53f16cc2b158 100644 --- a/packages/kit/test/apps/basics/test/client.test.js +++ b/packages/kit/test/apps/basics/test/client.test.js @@ -235,7 +235,7 @@ test.describe('Load', () => { // 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. expect(await page.textContent('h2')).toBe('a / b'); - expect(requests.filter((r) => !r.includes('_app/route'))).toEqual([]); + expect(requests.filter((r) => !r.includes('/__route.js'))).toEqual([]); }); test('permits 3rd party patching of fetch in universal load functions', async ({ page }) => { diff --git a/packages/kit/test/apps/basics/test/cross-platform/client.test.js b/packages/kit/test/apps/basics/test/cross-platform/client.test.js index c164a1593747..c1de68907024 100644 --- a/packages/kit/test/apps/basics/test/cross-platform/client.test.js +++ b/packages/kit/test/apps/basics/test/cross-platform/client.test.js @@ -864,7 +864,7 @@ test.describe('Routing', () => { await page.locator('button').click(); // Filter out server-side route resolution request - expect(requests.filter((r) => !r.includes('_app/route'))).toEqual([]); + expect(requests.filter((r) => !r.includes('__route.js'))).toEqual([]); expect(await page.textContent('h1')).toBe('updated'); expect(await page.textContent('h2')).toBe('form'); expect(await page.textContent('h3')).toBe('bar');