Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Would you have an example of how to do that?


Here’s a starting point:

  addEventListener("click", function (event) {
      const link = event.target.closest("a");
      if (
          !event.button &&
          !event.altKey &&
          !event.ctrlKey &&
          !event.metaKey &&
          !event.shiftKey &&
          link &&
          link.href.startsWith(location.origin + "/") &&
          link.target !== "_blank"
      ) {
          event.preventDefault();
          navigate(link.href);
      }
  }
There are some points of nuance here where you may want to vary (e.g. the determination of eligible hrefs, and handling of href targets), but this is the bones of it. You can also choose to add more functionality to it. Fastmail’s webmail, for example, uses this basic design, but also handles mailto: links specially (taking you to compose a new email), whitelists path patterns (since the domain is used for more than just the webmail app), and one or two other things.


I updated the repo for this (and credited you in the code). If you have time, please feel free to review & improve as looks like quite a few people are using the code now: https://github.com/ashok-khanna/react-snippets/blob/main/Rou...


Thanks for this. Does this add an event listener to "all" clicks or only for clicks on <a href>?


It gets called on all clicks (line 1, it’s a window-level click handler), then finds the link the click target is inside (line 2), and does nothing if it wasn’t inside a link (line 9).

(You might think that it should use .closest("a[href]") instead of .closest("a"), since a:not([href]) is not a link, but in that case, link.href === "", and so it fails the line 10 is-it-eligible-for-client-side-routing test. Note also that except for the “no href attribute” case, HTMLAnchorElement#href gives a full resolved URL, so <a href=""> will produce the document base URL.)

Fundamentally, there’s no such thing as an event handler that triggers only on links—you instead have to use a global event handler that starts by checking whether it’s being triggered on a link.


Thanks Chris, you are awesome - this is definitely a much better approach since it gets rid of an additional Link Component


I do think, though, that woojoo666’s comment and my response are worth bearing in mind. In this specific situation, I think <Link> is not warranted and mildly better avoided; but in a similar situation where global behaviour wasn’t already forced, I would say to keep the separate component, rather than breaking behavioural encapsulation.


Thank you, I agree




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: