Currently Hugo has two problems with its backlinks. First, take this multi-paragraph footnote in Markdown:

[^1-2018-05-26]: Some text

    > A blockquote

    Some more text

That renders with the backlink (↩︎) in a dedicated paragraph. It should instead be on the same line as “Some more text.” This is a burden in the land that affects more footnote systems than just Hugo’s, for the record.

The second problem is one that I universally fixed in Jekyll but that persists in Hugo, which is this: the backlink is not connected to the previous element via   — there’s rather a pure whitespace. This results in the backlink sometimes appearing on a dedicated line in isolation, due to text-wrapping. Instead, if the backlink must text-wrap to the next line, it should should always take its previous word along with it for improved continuity.

Rather than monkey with Hugo core - I don’t have time for that right now, unfortunately - the solution to both of these issues can be derived with this pure ES6 JavaScript.

const fixFootnotes = () => {
  const footnotes = [...document.getElementsByClassName('footnote-return')];
  footnotes.forEach(footnote => {
    const previousContent = footnote.previousSibling.textContent;
    if (previousContent === '\n ') {
      // Hugo has needlessly created a dedicated DOM node for the backlink, due 
      // likely to a multi-paragraph footnote. The solution is to move the backlink 
      // inline with the last node that actually contains footnote content.
      const whitespace = document.createTextNode("\u00A0");
      [whitespace, footnote].forEach(element =>
        footnote.previousSibling.previousSibling.appendChild(element));
    } else {
      const lastTwoChars = previousContent.substr(previousContent.length - 2, previousContent.length);
      if (lastTwoChars === '\n ') {
        // Replace the whitespace prior to backlink with   so the backlink is
        // never a widow.
        footnote.previousSibling.textContent = `${previousContent.substr(0, previousContent.length - 2)}\u00A0`;
      }
    }
  });
};
fixFootnotes();

Sure, it’s coding pretty close to the metal, but it works fantastically. I’m now using this code on Drinking Caffeine, and I invite you to be the judge on its superiority over the default behavior of backlinks in Hugo.1


  1. Once you have a grasp of how to do this level of DOM manipulation with JavaScript, an entire world of control opens up for you. It’s a good feeling. ↩︎