Footnote Citation Javascript

A brief guide for making footnote citations in Javascript that is ideal for citing the same link numerous times within the same page.

I needed to know how to do this and apparently it's not nearly as common as you'd think online to do it this way. Most examples and tutorials were not complex enough. Many footnotes on HTML pages are this horrible thing that is only ideal for less than 20 citations or something. And did not account for citing the same thing more than once. Here's one ideal for 50+ citations and citing the same source.

Disclaimer: I don't know much about Javascript. I did this with tutorials, stackoverflow, and trial and error.

Hints:
- you need to place the JS at the bottom of your HTML page
- it goes in a script tag
- the CSS part is obviously customizable

HTML needed:
Citations put after relevant sentences,

<span class="footnote" data-id="HERE"><span class="footnote-content" hidden>Text.</span></span>

Citation list placed at the bottom of the page (automatically created, just paste this),

<div class="footnotes">
<ol id="footnote-list">
</ol>
</div>

It will render out as this (minus my stylization of lists to use the arrow).

CSS used:

sup {
    font-size: 0.75em;
    line-height: 0;
}
sup a {
    font-size: 1em;
    text-decoration: none;
}
 .footnotes {
     margin-top: 2em;
     border-top: 1px solid #ccc;
     padding-top: 1em;
     font-size: 0.9em;
}
 .footnotes ol {
     padding-left: 1.2em;
}
 .back-link {
     margin-left: 0.5em;
     text-decoration: none;
}
 .footnote-number {
     font-weight: bold;
}
Will display repeated citations as "1-1", "1-2" and so on.
(function () {
  const footnotes = document.querySelectorAll('.footnote');
  const footnoteList = document.getElementById('footnote-list');
  const notesMap = new Map();
  let counter = 0;

  footnotes.forEach((fn) => {
    const id = fn.getAttribute('data-id');
    const contentEl = fn.querySelector('.footnote-content');
    const noteHTML = contentEl ? contentEl.innerHTML.trim() : '';

    if (!notesMap.has(id)) {
      counter++;
      notesMap.set(id, {
        number: counter,
        html: noteHTML,
        refs: []
      });
    }

    const noteData = notesMap.get(id);

    const sup = document.createElement('sup');
    const refIndex = noteData.refs.length + 1;

    const link = document.createElement('a');
    link.href = `#fn${noteData.number}`;
    link.id = `ref${noteData.number}-${refIndex}`;
    link.textContent = `${noteData.number}-${refIndex}`;

    sup.appendChild(link);
    fn.appendChild(sup);

    noteData.refs.push(link.id);
  });

    notesMap.forEach((note) => {
    const li = document.createElement('li');
    li.id = `fn${note.number}`;
    li.innerHTML =
    note.html + ' ' +
    note.refs.map((refId, i) =>
      `<a class="back-link" href="#${refId}" title="Back to text ${i + 1}">↩${i + 1}</a>`
    ).join(' ');

    footnoteList.appendChild(li);
  });
})();