Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions src/components/BackButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,27 @@ interface BackButtonProps {
mb?: number;
}

/**
* Determine whether the previous history entry likely belongs to this app.
* We consider it safe to go back only when we have an explicit navigation
* state marker (`fromApp`) set by internal links, **or** when the
* `document.referrer` points to the same origin.
*/
function isInAppNavigation(): boolean {
// If the previous navigation was performed by react-router (pushState),
// the referrer stays the current origin. For truly external arrivals
// (shared link, fresh tab, bookmark) the referrer is either empty or a
// different origin.
try {
const referrer = document.referrer;
if (!referrer) return false; // direct navigation, no referrer
const refUrl = new URL(referrer);
return refUrl.origin === window.location.origin;
} catch {
return false;
}
}

const BackButton: React.FC<BackButtonProps> = ({
label = 'Back',
to,
Expand All @@ -20,10 +41,11 @@ const BackButton: React.FC<BackButtonProps> = ({
const navigate = useNavigate();
const location = useLocation();
const state = (location.state as { backTo?: string }) || {};
const canGoBack = typeof window !== 'undefined' && window.history.length > 1;

const handleClick = () => {
if (canGoBack) {
// Only step through browser history when the previous entry is
// verifiably an in-app page. Otherwise fall back to a known route.
if (isInAppNavigation() && window.history.length > 1) {
navigate(-1);
return;
}
Expand Down