Skip to content

Instantly share code, notes, and snippets.

@devongovett
Last active May 10, 2024 14:48
Show Gist options
  • Save devongovett/919dc0f06585bd88af053562fd7c41b7 to your computer and use it in GitHub Desktop.
Save devongovett/919dc0f06585bd88af053562fd7c41b7 to your computer and use it in GitHub Desktop.
// Turn all HTML <a> elements into client side router links, no special framework-specific <Link> component necessary!
// Example using the Next.js App Router.
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
function useLinkHandler() {
let router = useRouter();
useEffect(() => {
let onClick = e => {
let link = e.target.closest('a');
if (
link &&
link instanceof HTMLAnchorElement &&
link.href &&
(!link.target || link.target === '_self') &&
link.origin === location.origin &&
!link.hasAttribute('download') &&
e.button === 0 && // left clicks only
!e.metaKey && // open in new tab (mac)
!e.ctrlKey && // open in new tab (windows)
!e.altKey && // download
!e.shiftKey &&
!e.defaultPrevented
) {
e.preventDefault();
router.push(link.href);
}
};
document.addEventListener('click', onClick);
return () => {
document.removeEventListener('click', onClick);
};
}, [router]);
}
@justindaking
Copy link

Wow

@Destitute-Streetdwelling-Guttersnipe

this is cool

@jviall
Copy link

jviall commented Jun 27, 2023

What about click with Enter when the anchor is focused?

@devongovett
Copy link
Author

Browsers fire the "click" event on Enter key press as well.

@longzheng
Copy link

The MDN docs for button seems to imply button could be remapped for left-handed use, so I wonder if e.button === 0 is not strictly always correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment