Is there a best practise way to get named anchor links rather than using IDs?

Bit of a novice, but I’ve got some legacy code to generate a Table of Contents based on adding an incremented ID to each of the H2 elements on a page.

As these can change order, I’d be hesitant to link to blah.com/help/article-1#4.

In the scenario that the anchor link’s H2 text is “Creating a post”, what can I do to this code to get the ID to be creating-a-post, resulting in the dynamic link being blah.com/help/article-1#creating-a-post?

const $headers = $(".article-body > h2, h3");

$headers.each((i, el) => {
  const $el = $(el);

  // skip it if it already has a link inside
  if ($el.has("a").length != 0) {
    return;
  }

  let idToLink = "";

  // skip it if it already has an id
  if ($el.attr("id") === undefined) {
    // give it ID to match
    idToLink = "" + i;
    $el.attr("id", idToLink);
  } else {
    // make sure the ID matches
    idToLink = $el.attr("id");
  }
});

$(document).ready(function () {
            setTimeout(() => {
                // Get ToC div
                if(document.querySelectorAll('.article-body > h2').length > 0) {
                
                toc = document.getElementById("ToC"); 
              //Add a header
                tocHeader = document.createElement("h2");
                tocHeader.innerText = "In this article";
                toc.appendChild(tocHeader); 
              // Get the h2 tags — ToC entries

                tocList = document.createElement("ul");
                // tocContainer.appendChild(tocList);
                // document.getElementById("div").appendChild(tocList);

                $('.article-body > h2').each(function () {
                    tocListItem = document.createElement("li");
                    // a link for the h2
                    tocEntry = document.createElement("a");
                    tocEntry.setAttribute("href", "#" + $(this).attr('id'));
                    tocEntry.innerText = $(this).text();
                    tocListItem.appendChild(tocEntry);
                    tocList.appendChild(tocListItem);
                });
                toc.appendChild(tocList);

                }
            });
        });

Is this even the best route?