fix: harden external link navigation in the web app
- add a shared external-navigation guard at the document level - route onboarding, markdown, settings, and node source links through one helper - stop browser fallback code from replacing the current app page on failures Generated with Codex
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { openExternalUrl, shouldOpenExternally } from "@/utils/openExternalUrl";
|
||||
|
||||
export default function ExternalNavigationManager() {
|
||||
useEffect(() => {
|
||||
const handleDocumentClick = (event: MouseEvent) => {
|
||||
if (event.defaultPrevented || event.button !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = event.target;
|
||||
if (!(target instanceof Element)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const anchor = target.closest("a[href]");
|
||||
if (!(anchor instanceof HTMLAnchorElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rawHref = anchor.getAttribute("href");
|
||||
if (!rawHref || rawHref.startsWith("#") || anchor.hasAttribute("download")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shouldOpenExternally(rawHref)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
void openExternalUrl(anchor.href || rawHref).catch((error) => {
|
||||
console.error("[external] document click open failed", error);
|
||||
window.alert(`Unable to open this link automatically.\n\n${anchor.href || rawHref}`);
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener("click", handleDocumentClick, true);
|
||||
return () => {
|
||||
document.removeEventListener("click", handleDocumentClick, true);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user