Search code examples
reactjstypescriptmarkdownreact-markdownremark-gfm

How to render footnotes with missing definitions using react-markdown and remark-gfm


I'm creating a react app that uses react-markdown to render arbitrary markdown, and I would like to support GFM via remark-gfm, or some other method. Here is my component:

import { FC } from "react";
import ReactMarkdown from "react-markdown";                                      
import remarkGfm from "remark-gfm";

interface Props {
  content: string;
}

const MessageContent: FC<Props> = ({ content }) => {

  return (
    <ReactMarkdown children={content} remarkPlugins={[remarkGfm]} />
  );
}

export default MessageContent;

The above works, but I've noticed that if the markdown contains a footnote, and the footnote definition is missing, it will be ignored by remark-gfm. For exampe, if my markdown looks like this:

## Footnote

A note[^1]

A second note [^2]

[^1]: Big note.

The number 1 footnote will be handled as expected by remark-gfm, but the number 2 footnote will seemingly be ignored, and not converted to superscript.

Is there a way to get the number 2 footnote to at-least render as superscript, in this case?


Solution

  • Use the raw HTML <sup> tag.

    Not a footnote.<sup>2</sup>
    

    Note that footnotes are not part of the CommonMark spec or GitHub's extended spec. There were not even supported by John Gruber's original implementation (despite the fact that he regularly uses them on his site). Therefore the expected behavior for footnotes is not fully defined. However, the behavior you are getting is the expected behavior in any implementation I have ever seen that includes support. Specifically, a footnote marker is only recognized as such if there is a matching footnote definition.

    This behavior is consistent with other reference style syntax which is more fully specified. For example, reference links include the requirement that a link label "matches a link reference definition elsewhere in the document." Admittedly, the spec does not specifically say what should happen if there is no match, but a quick test reveals that the link is not parsed as one by the Commonmark reference implementation.

    [foo][bar]
    [foo][baz]
    
    [bar]: /url "title"
    

    is rendered as

    <p><a href="/url" title="title">foo</a>
    [foo][baz]</p>
    

    Therefore, in your case, because there is no matching definition, [^2] is not a footnote marker and is not processed as one. As the original rules for Markdown state:

    For any markup that is not covered by Markdown’s syntax, you simply use HTML itself.

    Of course, if you want to create your own extension which parses unmatched markers as superscripts, you can. However, that would be out-of-scope here.