From fa31fa0cafe5f0b4022551a597ac069814124c00 Mon Sep 17 00:00:00 2001 From: Till JS Date: Fri, 17 Apr 2026 15:08:25 +0200 Subject: [PATCH] fix(workbench): handle ?app= deep-links reactively while page is mounted The onMount handler only fires once, so clicking a /?app=settings link from the companion chat (or any in-app link) while already on the workbench page did nothing. Add a reactive $effect that watches $page.url.searchParams for 'app' changes and opens/scrolls to the target panel on every navigation, not just on initial mount. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../apps/web/src/routes/(app)/+page.svelte | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/apps/mana/apps/web/src/routes/(app)/+page.svelte b/apps/mana/apps/web/src/routes/(app)/+page.svelte index 348d43c0c..48cfc4e5c 100644 --- a/apps/mana/apps/web/src/routes/(app)/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/+page.svelte @@ -82,6 +82,25 @@ history.replaceState({}, '', clean); } }); + // Reactive deep-link: handles `/?app=…` navigations that happen + // while the page is already mounted (e.g. clicking a link inside + // the companion chat). onMount only fires once; this $effect + // re-runs whenever the URL search params change. + $effect(() => { + const target = $page.url.searchParams.get('app'); + if (!target || !getApp(target)) return; + // Use queueMicrotask so we don't mutate state during the effect's first run + queueMicrotask(async () => { + const already = workbenchScenesStore.openApps.find((a) => a.appId === target); + if (!already) await workbenchScenesStore.addApp(target); + await tick(); + scrollToPage(target); + const clean = new URL($page.url); + clean.searchParams.delete('app'); + history.replaceState({}, '', clean); + }); + }); + onDestroy(() => { workbenchScenesStore.dispose(); bottomBarStore.clear();