From 2113759e5cd328d2d9ba4ab7f0936253f0b834ec Mon Sep 17 00:00:00 2001 From: Antoine Kingue Date: Sun, 25 May 2025 02:01:25 +0200 Subject: [PATCH 1/3] fix: maintain smart back button behavior with view transitions (#291) --- src/components/BackButton/index.tsx | 36 +++++++++++++++++++---------- src/layouts/RootLayout.astro | 16 +++++++++++++ 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/components/BackButton/index.tsx b/src/components/BackButton/index.tsx index 7e4be548..be113cd6 100644 --- a/src/components/BackButton/index.tsx +++ b/src/components/BackButton/index.tsx @@ -1,27 +1,39 @@ import { Button } from "@/components/ui/button"; import type { ReactNode } from "react"; import { MdArrowBack } from "react-icons/md"; +import { useEffect, useState } from "react"; export const BackButton = (props: { href: string; buttonLabel?: ReactNode; contextLabel?: ReactNode; }) => { + const [canGoBack, setCanGoBack] = useState(false); + + useEffect(() => { + const checkBackNavigation = () => { + setCanGoBack(window.history.length > 1); + }; + + checkBackNavigation(); + document.addEventListener("astro:page-load", checkBackNavigation); + + return () => { + document.removeEventListener("astro:page-load", checkBackNavigation); + }; + }, []); + + const handleClick = (e: React.MouseEvent) => { + if (canGoBack) { + e.preventDefault(); + window.history.back(); + } + }; + return (
diff --git a/src/layouts/RootLayout.astro b/src/layouts/RootLayout.astro index a11b1566..a1142995 100644 --- a/src/layouts/RootLayout.astro +++ b/src/layouts/RootLayout.astro @@ -1,4 +1,5 @@ --- +import { ClientRouter } from "astro:transitions"; import Analytics from "@vercel/analytics/astro"; import "@fontsource/tomorrow/400.css"; import "@fontsource/tomorrow/500.css"; @@ -30,8 +31,23 @@ import { Toaster } from "@/components/ui/sonner"; /> + + + Date: Sun, 25 May 2025 02:01:25 +0200 Subject: [PATCH 2/3] fix: improve back button navigation logic with visited paths tracking --- src/components/BackButton/index.tsx | 32 +++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/components/BackButton/index.tsx b/src/components/BackButton/index.tsx index be113cd6..0220c925 100644 --- a/src/components/BackButton/index.tsx +++ b/src/components/BackButton/index.tsx @@ -1,30 +1,36 @@ import { Button } from "@/components/ui/button"; import type { ReactNode } from "react"; import { MdArrowBack } from "react-icons/md"; -import { useEffect, useState } from "react"; +import { useEffect } from "react"; + +const VISITED_PATHS_KEY = "visited-paths"; export const BackButton = (props: { href: string; buttonLabel?: ReactNode; contextLabel?: ReactNode; }) => { - const [canGoBack, setCanGoBack] = useState(false); - useEffect(() => { - const checkBackNavigation = () => { - setCanGoBack(window.history.length > 1); - }; - - checkBackNavigation(); - document.addEventListener("astro:page-load", checkBackNavigation); + const currentPath = window.location.pathname; + const storedPaths = sessionStorage.getItem(VISITED_PATHS_KEY); + const visitedPaths = storedPaths ? JSON.parse(storedPaths) : []; - return () => { - document.removeEventListener("astro:page-load", checkBackNavigation); - }; + if (!visitedPaths.includes(currentPath)) { + visitedPaths.push(currentPath); + sessionStorage.setItem(VISITED_PATHS_KEY, JSON.stringify(visitedPaths)); + } }, []); const handleClick = (e: React.MouseEvent) => { - if (canGoBack) { + const referrer = document.referrer; + const hasReferrer = !!referrer && referrer.includes(window.location.host); + const hasHistory = window.history.length > 1; + + const storedPaths = sessionStorage.getItem(VISITED_PATHS_KEY); + const visitedPaths = storedPaths ? JSON.parse(storedPaths) : []; + const hasVisitedPaths = visitedPaths.length > 1; + + if (hasHistory && (hasReferrer || hasVisitedPaths)) { e.preventDefault(); window.history.back(); } From b343fa6e629474ff6e69ff01bc2a0d5dac3798cb Mon Sep 17 00:00:00 2001 From: Antoine Kingue Date: Sun, 25 May 2025 02:35:41 +0200 Subject: [PATCH 3/3] fix: ensure maximum visited paths limit is enforced in back button logic --- src/components/BackButton/index.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/BackButton/index.tsx b/src/components/BackButton/index.tsx index 0220c925..b8083936 100644 --- a/src/components/BackButton/index.tsx +++ b/src/components/BackButton/index.tsx @@ -4,6 +4,7 @@ import { MdArrowBack } from "react-icons/md"; import { useEffect } from "react"; const VISITED_PATHS_KEY = "visited-paths"; +const MAX_VISITED_PATHS = 10; export const BackButton = (props: { href: string; @@ -13,10 +14,15 @@ export const BackButton = (props: { useEffect(() => { const currentPath = window.location.pathname; const storedPaths = sessionStorage.getItem(VISITED_PATHS_KEY); - const visitedPaths = storedPaths ? JSON.parse(storedPaths) : []; + let visitedPaths = storedPaths ? JSON.parse(storedPaths) : []; if (!visitedPaths.includes(currentPath)) { visitedPaths.push(currentPath); + + if (visitedPaths.length > MAX_VISITED_PATHS) { + visitedPaths = visitedPaths.slice(-MAX_VISITED_PATHS); + } + sessionStorage.setItem(VISITED_PATHS_KEY, JSON.stringify(visitedPaths)); } }, []);