Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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/breezy-bananas-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': major
---

breaking: refresh all load functions/queries when clicking a link to the current URL
21 changes: 12 additions & 9 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -661,13 +661,13 @@ function persist_state() {

/**
* @param {string | URL} url
* @param {{ replace?: boolean; reset?: boolean; refreshAll?: boolean; invalidate?: Array<string | URL | ((url: URL) => boolean)>; state?: Record<string, any>; persistState?: boolean }} options
* @param {number} redirect_count
* @param {{ type?: import('@sveltejs/kit').NavigationType; replace?: boolean; reset?: boolean; refreshAll?: boolean; invalidate?: Array<string | URL | ((url: URL) => boolean)>; state?: Record<string, any>; persistState?: boolean; event?: Event }} [options]
* @param {number} [redirect_count]
* @param {{}} [nav_token]
* @param {NavigationIntent | undefined} [intent] navigation intent, when already known by the caller (avoids recomputing it)
* @returns {Promise<void>}
*/
export async function _goto(url, options, redirect_count, nav_token, intent) {
export async function _goto(url, options = {}, redirect_count = 0, nav_token = {}, intent) {
/** @type {Set<string>} */
let query_keys;
/** @type {Set<string>} */
Expand All @@ -680,12 +680,13 @@ export async function _goto(url, options, redirect_count, nav_token, intent) {
}

await navigate({
type: 'goto',
type: options.type ?? 'goto',
url: resolve_url(url),
reset: options.reset,
replace_state: options.replace,
state: options.state,
persist_state: options.persistState,
event: options.event,
redirect_count,
nav_token,
intent,
Expand Down Expand Up @@ -1607,7 +1608,7 @@ async function load_root_error_page({ error, url, route }) {
// client-side navigation if the root layout loader throws a redirect while
// rendering the default error page
if (error instanceof Redirect) {
await _goto(new URL(error.location, location.href), {}, 0);
await _goto(new URL(error.location, location.href));
return;
}

Expand Down Expand Up @@ -2892,7 +2893,7 @@ export async function applyAction(result) {
if (result.type === 'error') {
await set_nearest_error_page(result.error);
} else if (result.type === 'redirect') {
await _goto(result.location, { refreshAll: true }, 0);
await _goto(result.location, { refreshAll: true });
} else {
page.form = result.data;
page.status = result.status;
Expand Down Expand Up @@ -3108,11 +3109,13 @@ function _start_router() {
setTimeout(fulfil, 100); // fallback for edge case where rAF doesn't fire because e.g. tab was backgrounded
});

await navigate({
const changed = url.href !== location.href;

Comment thread
vercel[bot] marked this conversation as resolved.
await _goto(url, {
type: 'link',
url,
reset: options.reset,
replace_state: options.replace_state ?? url.href === location.href,
replace: options.replace_state ?? !changed,
refreshAll: !changed,
event
});
});
Expand Down
10 changes: 3 additions & 7 deletions packages/kit/src/runtime/client/remote-functions/form.svelte.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,9 @@ export function form(id) {

if (response.redirect) {
// Use internal version to allow redirects to external URLs
void _goto(
response.redirect,
{
refreshAll: should_refresh
},
0
);
void _goto(response.redirect, {
refreshAll: should_refresh
});
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export function prerender(id) {

if (result.redirect) {
// Use internal version to allow redirects to external URLs
void _goto(result.redirect, {}, 0);
void _goto(result.redirect);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function query_batch(id) {

if (response.redirect) {
// Use internal version to allow redirects to external URLs
await _goto(response.redirect, {}, 0);
await _goto(response.redirect);

// settle all batched promises (with `undefined`, like a redirect
// from a non-batched query) so that callers don't hang forever
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function query(id) {

if (result.redirect) {
// Use internal version to allow redirects to external URLs
await _goto(result.redirect, {}, 0);
await _goto(result.redirect);
}
});
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export async function remote_request(url, init) {
export async function handle_side_channel_response(response) {
if (response.type === 'redirect') {
// Use internal version to allow redirects to external URLs
await _goto(response.location, {}, 0);
await _goto(response.location);
throw new Redirect(307, response.location);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script>
import { increment, get_count, reset } from './data.remote.js';
</script>

<button id="reset" onclick={() => reset()}>reset</button>
<button id="increment" onclick={() => increment()}>increment</button>

<a id="count" href="/remote/link-refresh">{await get_count()}</a>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { command, query } from '$app/server';

let count = 0;

export const reset = command(() => {
count = 0;
get_count().refresh();
});

export const increment = command(() => {
count += 1;
// don't refresh!
});

export const get_count = query(() => count);
15 changes: 15 additions & 0 deletions packages/kit/test/apps/async/test/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ test.describe('remote functions', () => {
expect(response.headers()['cache-control']).toBe('private, no-store');
});

test('clicking a link to the current page refreshes active queries', async ({ page }) => {
await page.goto('/remote/link-refresh');
await page.locator('#reset').click();

const a = page.locator('#count');

await expect(a).toHaveText('0');

await page.locator('#increment').click();
await expect(a).toHaveText('0');

await a.click();
await expect(a).toHaveText('1');
});

test('packages can re-export remote functions', async ({ page }) => {
await page.goto('/remote-lib');
await expect(page.locator('h1')).toHaveText('lib says hello');
Expand Down
Loading