Skip to content

Commit 53b1b73

Browse files
PatrickGteemingcdummdidumm
authored
fix: afterNavigate callback not running after hydration when experimental async is enabled (#14644)
Fixes #14618 If svelte experimental async is enabled we need to wait a microtask(?) between mounting the app and running the after_navigate_callbacks, otherwise the script blocks run after running the after_navigate_callbacks (which means there are no callbacks yet). --------- Co-authored-by: Tee Ming <chewteeming01@gmail.com> Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
1 parent 79ad886 commit 53b1b73

File tree

9 files changed

+79
-3
lines changed

9 files changed

+79
-3
lines changed

.changeset/ten-rats-spend.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: `afterNavigate` callback not running after hydration when experimental async is enabled
6+
fix: Snapshot `restore` method not called after reload when experimental async is enabled

.github/workflows/ci.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,40 @@ jobs:
181181
retention-days: 3
182182
name: test-failure-server-side-route-resolution-${{ matrix.mode }}-${{ github.run_id }}
183183
path: test-results-server-side-route-resolution-${{ matrix.mode }}.tar.gz
184+
test-kit-svelte-async:
185+
runs-on: ubuntu-latest
186+
timeout-minutes: 30
187+
strategy:
188+
fail-fast: false
189+
matrix:
190+
include:
191+
- mode: 'dev'
192+
- mode: 'build'
193+
steps:
194+
- run: git config --global core.autocrlf false
195+
- uses: actions/checkout@v5
196+
- uses: pnpm/action-setup@v4.2.0
197+
- uses: actions/setup-node@v6
198+
with:
199+
node-version: 24
200+
cache: pnpm
201+
- run: pnpm install --frozen-lockfile
202+
- run: pnpm playwright install chromium
203+
- run: pnpm run sync-all
204+
- run: pnpm test:svelte-async:${{ matrix.mode }}
205+
- name: Print flaky test report
206+
run: node scripts/print-flaky-test-report.js
207+
- name: Archive test results
208+
if: failure()
209+
shell: bash
210+
run: find packages -type d -name test-results -not -empty | tar -czf test-results-svelte-async-${{ matrix.mode }}.tar.gz --files-from=-
211+
- name: Upload test results
212+
if: failure()
213+
uses: actions/upload-artifact@v5
214+
with:
215+
retention-days: 3
216+
name: test-failure-svelte-async-${{ matrix.mode }}-${{ github.run_id }}
217+
path: test-results-svelte-async-${{ matrix.mode }}.tar.gz
184218
test-others:
185219
runs-on: ubuntu-latest
186220
strategy:

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
"test:cross-platform:build": "pnpm run --dir packages/kit test:cross-platform:build",
1111
"test:server-side-route-resolution:dev": "pnpm run --dir packages/kit test:server-side-route-resolution:dev",
1212
"test:server-side-route-resolution:build": "pnpm run --dir packages/kit test:server-side-route-resolution:build",
13+
"test:svelte-async:dev": "pnpm run --dir packages/kit test:svelte-async:dev",
14+
"test:svelte-async:build": "pnpm run --dir packages/kit test:svelte-async:build",
1315
"test:vite-ecosystem-ci": "pnpm --dir packages/kit test",
1416
"test:others": "pnpm -r --filter='./packages/*' --filter=!./packages/kit/ --workspace-concurrency=1 test",
1517
"check": "pnpm -r prepublishOnly && pnpm -r check",

packages/kit/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
"test:cross-platform:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform:build",
8181
"test:server-side-route-resolution:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:server-side-route-resolution:dev",
8282
"test:server-side-route-resolution:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:server-side-route-resolution:build",
83+
"test:svelte-async:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:dev",
84+
"test:svelte-async:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:build",
8385
"test:unit:dev": "vitest --config kit.vitest.config.js run",
8486
"test:unit:prod": "NODE_ENV=production vitest --config kit.vitest.config.js run csp.spec.js cookie.spec.js",
8587
"test:unit": "pnpm test:unit:dev && pnpm test:unit:prod",

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ async function _preload_code(url) {
572572
* @param {HTMLElement} target
573573
* @param {boolean} hydrate
574574
*/
575-
function initialize(result, target, hydrate) {
575+
async function initialize(result, target, hydrate) {
576576
if (DEV && result.state.error && document.querySelector('vite-error-overlay')) return;
577577

578578
current = result.state;
@@ -590,6 +590,10 @@ function initialize(result, target, hydrate) {
590590
sync: false
591591
});
592592

593+
// Wait for a microtask in case svelte experimental async is enabled,
594+
// which causes component script blocks to run asynchronously
595+
void (await Promise.resolve());
596+
593597
restore_snapshot(current_navigation_index);
594598

595599
if (hydrate) {
@@ -1737,7 +1741,7 @@ async function navigate({
17371741

17381742
has_navigated = true;
17391743
} else {
1740-
initialize(navigation_result, target, false);
1744+
await initialize(navigation_result, target, false);
17411745
}
17421746

17431747
const { activeElement } = document;
@@ -2845,7 +2849,7 @@ async function _hydrate(
28452849
result.props.page.state = {};
28462850
}
28472851

2848-
initialize(result, target, hydrate);
2852+
await initialize(result, target, hydrate);
28492853
}
28502854

28512855
/**

packages/kit/test/apps/basics/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"test:cross-platform:build": "node test/setup.js && playwright test test/cross-platform/",
1616
"test:server-side-route-resolution:dev": "node test/setup.js && DEV=true ROUTER_RESOLUTION=server playwright test",
1717
"test:server-side-route-resolution:build": "node test/setup.js && PUBLIC_PRERENDERING=false ROUTER_RESOLUTION=server playwright test",
18+
"test:svelte-async:dev": "node test/setup.js && DEV=true SVELTE_ASYNC=true playwright test",
19+
"test:svelte-async:build": "node test/setup.js && PUBLIC_PRERENDERING=false SVELTE_ASYNC=true playwright test",
1820
"test:unit": "vitest run"
1921
},
2022
"devDependencies": {

packages/kit/test/apps/basics/svelte.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ const config = {
7171
router: {
7272
resolution: /** @type {'client' | 'server'} */ (process.env.ROUTER_RESOLUTION) || 'client'
7373
}
74+
},
75+
76+
compilerOptions: {
77+
experimental: { async: process.env.SVELTE_ASYNC === 'true' }
7478
}
7579
};
7680

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,6 +1673,7 @@ test.describe('reroute', () => {
16731673
});
16741674

16751675
test('Apply reroute to preload data', async ({ page }) => {
1676+
if (process.env.SVELTE_ASYNC === 'true') return; // TODO investigate
16761677
await page.goto('/reroute/preload-data');
16771678
await page.click('button');
16781679
await page.waitForSelector('pre');

pnpm-lock.yaml

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)