diff --git a/.changeset/great-schools-cross.md b/.changeset/great-schools-cross.md new file mode 100644 index 000000000000..4280708e2cf9 --- /dev/null +++ b/.changeset/great-schools-cross.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: ensure `beforeNavigate` works on other navigations after clicking a download link diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index f91728bccc2c..bb093db884fa 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -140,10 +140,16 @@ function clear_onward_history(current_history_index, current_navigation_index) { * Returns a `Promise` that never resolves (to prevent any * subsequent work, e.g. history manipulation, from happening) * @param {URL} url + * @returns {Promise} */ function native_navigation(url) { location.href = url.href; - return new Promise(() => {}); + return new Promise((resolve) => { + // if we're still on the same page, it was probably a download + if (location.href !== url.href) { + resolve(undefined); + } + }); } function noop() {} @@ -1293,6 +1299,13 @@ async function navigate({ }), 404 ); + + // do nothing if we downloaded a file and are still on the same page + if (!navigation_result) { + stores.navigating.set(null); + nav.fulfil(undefined); + return; + } } // if this is an internal navigation intent, use the normalized @@ -1998,6 +2011,9 @@ function _start_router() { before_navigate_callbacks.forEach((fn) => fn(navigation)); } + // We need to reset the flag manually here because clicking on an + // implicit download link does not reset it for the next navigation. + navigating = false; if (should_block) { e.preventDefault(); diff --git a/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/download/+server.js b/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/download/+server.js new file mode 100644 index 000000000000..cbd6a2aae8e8 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/download/+server.js @@ -0,0 +1,7 @@ +export function GET() { + return new Response('ok', { + headers: { + 'Content-Disposition': 'attachment' + } + }); +} diff --git a/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/prevent-navigation/+page.svelte b/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/prevent-navigation/+page.svelte index 67607376e397..a325e425bd51 100644 --- a/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/prevent-navigation/+page.svelte +++ b/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/prevent-navigation/+page.svelte @@ -1,13 +1,21 @@