"use client"; import { useEffect } from "react"; import { usePathname } from "next/navigation"; import { LAST_PAGE_KEY, isRecordable } from "@/lib/last-page"; // The recorder rides in the root layout and writes down where you are. What // reads it back is components/dashboard/ResumeChip.tsx, which offers the URL as // a link on the dashboard -- / stopped being a doorway when it became a page. // // Neither uses useSearchParams(). That hook demands a Suspense boundary, and // this app has none anywhere on purpose -- putting the first one in the root // layout to satisfy a nav recorder would be the tail wagging the dog, with a // real risk of pushing every route out of static rendering. window.location // read inside an effect is the house pattern (Deck.tsx, MixBench.tsx, // Waveform.tsx) and gives the query string for free. /** pathname + query, exactly as the address bar has it. */ function here(): string { return window.location.pathname + window.location.search; } function remember() { // Private mode, a full quota, storage disabled by policy: none of these are // worth breaking a page over. Forgetting where you were is the cost. try { const url = here(); if (isRecordable(url)) localStorage.setItem(LAST_PAGE_KEY, url); } catch { /* not remembering is not an error */ } } /** * Mounted once, in the root layout. Renders nothing. * * usePathname() fires on every navigation, which covers moving between pages. * It does NOT move when only the query changes -- /browse/find rewriting ?q= as * you search stays one pathname -- so `pagehide` records too, which doubles as * the honest capture of the URL you were on when you closed the tab. */ export function LastPageRecorder() { const pathname = usePathname(); useEffect(() => { remember(); window.addEventListener("pagehide", remember); return () => window.removeEventListener("pagehide", remember); }, [pathname]); return null; }