Saturday 26 October 2024

React and Markdown: Better to intercept or replace anchor elements in markdown?

We're setting up an Archery Wiki on our site and using Firebase as our back end. Adding wikis is simple enough, as we can use a simple markdown editor, and displaying them is easy enough using the marvellous react-markdown package. However, navigation triggered a whole page refresh, which was less than ideal.

I thought there must be a way of intercepting anchor element clicks in React, but after searching for a while, I realised that intercepting clicks on all links was less than ideal anyway. Wouldn't it be better to listen to internal links, replace them with pseudo anchor elements, and trigger React's navigation instead?

So that's what I did!

This is the relevant component in context:

<ReactMarkdown
  components={{
    a: (props) => {
      return props.href.startsWith(
        "https://witchfordarchers.club/wiki/",
      ) ? (
        <span
          style={{
            cursor: "pointer",
            textDecoration: "underline",
          }}
          title={props.href.replace(
            "https://witchfordarchers.club/wiki/",
            "",
          )}
          onClick={handleNavigation.bind(
            this,
            props.href.replace("https://witchfordarchers.club/wiki/", ""),
          )}
        >
          {props.children}
        </span>
      ) : (
        <a href={props.href}>{props.children}</a> // All other links
      );
    },
  }}
>
  {wiki.content}
</ReactMarkdown>

Of course, it requires a handleNavigation handler being passed down, but that's dead simple to add to the calling page.

This is an example of the code working, and this is the implementation on Witchford Archers.

No comments:

Post a Comment