From 443702d222fa73c30ea50d5047a3fe2381d0a061 Mon Sep 17 00:00:00 2001 From: Ole-Morten Duesund Date: Mon, 25 May 2026 18:48:34 +0200 Subject: [PATCH] =?UTF-8?q?fix(spa):=20back=20button=20respects=20history;?= =?UTF-8?q?=20auto-redirect=20/=20=E2=86=92=20/hjem=20when=20logged=20in?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two related navigation fixes: 1. Back-button now uses real browser history. Sub-view "Tilbake" buttons (permalink, tag page, personvern, public list) all used to call goPublicHome() — which always sent the user to / — instead of returning to wherever they came from. Replaced with a single backToCallerOrHome() that delegates to navigate.goBack(fallback), which calls window.history.back() if there's a prior entry, else navigates to /hjem (or / when anonymous) so cold-loaded permalinks still have somewhere to go. 2. Cold-load redirect: a logged-in user landing on / probably wants their own dashboard, not the public marketing surface. After the me-probe finishes in onMount, if the initial route was 'public-home' and session.user exists, push to /hjem instead of applying the public-home route. This only runs on initial mount (not on every popstate), so browser-back from /hjem to / still works if the user explicitly navigates there. The wordmark in the nav also picks its destination by auth state now — logged-in users go to /hjem, anonymous users to /. Otherwise clicking it post-redirect would just bounce back to /hjem. --- frontend/src/App.svelte | 45 ++++++++++++++++++++++-------------- frontend/src/lib/navigate.ts | 18 +++++++++++++++ 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index 3534856..324a90b 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -3,6 +3,7 @@ import { ready } from './lib/crypto'; import { api, ApiError } from './lib/api'; import { session, setSessionUserOnly } from './lib/session.svelte'; + import { goBack } from './lib/navigate'; import { logout } from './lib/auth'; import Login from './components/Login.svelte'; import Signup from './components/Signup.svelte'; @@ -138,7 +139,18 @@ // No session — fine. } - applyRoute(route); + // Cold-load redirect: a logged-in user landing on the public landing + // probably wants their own dashboard, not the marketing-y "what is this" + // page. We only redirect on this initial mount — not on every + // applyRoute call — so browser-back from /hjem to / still lets the + // explicit navigation through (no loop, and the wordmark intentionally + // sends logged-in users to /hjem instead of / anyway). + if (route.view === 'public-home' && session.user) { + pushUrl('/hjem'); + view = 'home'; + } else { + applyRoute(route); + } }); function applyRoute(route: Route) { @@ -164,22 +176,20 @@ } } - function leaveTag() { - // Same logic as leavePersonvern — back to wherever they were. - if (session.user) goHome(); - else goPublicHome(); - } - function goPersonvern() { pushUrl('/personvern'); view = 'personvern'; } - function leavePersonvern() { - // Send the visitor wherever they "would have been" — landing if logged out, - // dashboard if logged in. Either is more useful than staying on the doc page. - if (session.user) goHome(); - else goPublicHome(); + /** + * Back-button handler for sub-views (permalink, tag page, personvern, + * public list). Uses real browser history so the user returns to + * wherever they came from in the SPA — /hjem, /etiketter/foo, + * /aktivitet/bar, anywhere. Falls back to /hjem (or / when anonymous) + * on cold-loads where there's no prior history entry. + */ + function backToCallerOrHome() { + goBack(session.user ? '/hjem' : '/'); } function onAuthed() { @@ -207,7 +217,8 @@