Generate Table of Contents with a single click

Generate Table of Contents with a single click


4 min read

After writing down and publishing my longest write-up I thought that this is too hard to read, and I desperately need the table of contents for it. I did a quick research and found out that indeed it is possible, I scripted that out - and now I'm sharing that with you ๐Ÿ™Œ

The basic idea comes from the Sai Laasya Vabilisetty article from Markdown Cheatsheet to Write a Stunning Article!

What does it look like?

For article code:

# What does it look like?


# Regular, laborious way


# Preferred version


# Wrapping up


# Bonus materials


The final result looks like this:


  1. What does it look like?
  2. Regular, laborious way
  3. Preferred version
  4. Wrapping up
  5. Bonus materials

Regular, laborious way

Just type it in manually.

# Contents

1. [What does it look like?](#what-does-it-look-like)
2. [Regular, laborious way](#regular-laborious-way)
3. [Preferred version](#preferred-version)
4. [Wrapping up](#wrapping-up)
5. [Bonus materials](#bonus-materials)

Preferred version

Go into Preview mode (for already published articles Edit -> Preview) and paste the following code into the Developer Tools Console.


  • Numbered list

Minified, one liner:

let ct="***\n# Contents\n";$("h1").each((i,e) => {ct+=`${i+1}. [${e.innerHTML}](#${})\n`});console.log(ct+="***");

Pretty print

let ct = "***\n# Contents\n";
$("h1").each((i, e) => {
    ct += `${i+1}. [${e.innerHTML}](#${})\n`
console.log(ct += "***");
  • Bullet list

Minified, one liner:

let ct="***\n# Contents\n";$("h1").each((i,e) => {ct+=`* [${e.innerHTML}](#${})\n`});console.log(ct+="***");

Pretty print

let ct = "***\n# Contents\n";
$("h1").each((i, e) => {
    ct += `* [${e.innerHTML}](#${})\n`
console.log(ct += "***");

The above JavaScript uses the fact that the only h1 tags available on the Preview are the # headings existing in the article.

Wrapping up

๐Ÿ”” CyberEthical.Me is maintained purely from your donations - consider one-time sponsoring on the Sponsor button or ๐ŸŽ become a Patron which also gives you some bonus perks.

Now copy the output of the script from the console and paste it, preferably, somewhere at the top of the article.

Just don't use it as an article opener - when sharing your post on social, sometimes first lines of text land in the preview - this won't look good with all headers scrabled together.

Bonus materials

Go to top

Kudos to Jordan Craig for this comment in the article from Amarachi Emmanuela Azubuike

Now, when you have the table of contents, it is good to have "Go to top" action links spread inside the article, so the reader can easily jump back and forth between headings and listing.

[Back to top](#contents) โคด

It looks and acts (click it) like this:

Back to top โคด

Go fancy

As you can see, the presented method requires you to update table of contents each time heading text changes - because the anchor link will be broken and will no longer link to the section.

There is a more tedious but universal workaround by using own anchors.

# Go fancy <a id="fancy"></a>

That way, you can jump to any location where the anchor is placed. Code for this will look like this:

1. [Go fancy!](#fancy)

Try it out:

  1. Go fancy!

Now, then - how to automate this?

Assuming you have already anchored your article - use the following snippets:

  • Numbered list

    let ct="***\n# Contents\n"; $("a[id]").each((i,e) => {ct+=`${i+1}. [](#${})\n`});console.log(ct+="***");
  • Bullet list

    let ct="***\n# Contents\n"; $("a[id]").each((i,e) => {ct+=`* [](#${})\n`});console.log(ct+="***");

Because this is universal method - first time you have to fill in the titles of anchors - but after that, you can modify text of headers or other elements to your liking.

๐Ÿ“Œ Follow the #CyberEthical hashtag on the social media

๐Ÿ‘‰ Instagram:

๐Ÿ‘‰ LinkedIn: Kamil Gierach-Pacanek

๐Ÿ‘‰ Twitter: @cyberethical_me

๐Ÿ‘‰ Facebook: @CyberEthicalMe

Bookmark Action

And now my favorite one.

This may not work in all browsers - compatibility table.

In your browser, add new page to bookmarks


In the title, add text you want to be displayed on Bookmarks bar, and in the URL paste the following one liner:

javascript:(function() {$("[id='contents-clip']").remove();let ct="***\n# Contents\n";$("h1").each((i,e) => {ct+=`* [${e.innerHTML}](#${})\n`});navigator.clipboard.writeText(ct+="***").then(function() {}, function(err) {console.error(err);});}());


Pretty print:

javascript: (function() {
    let ct = "***\n# Contents\n";
    $("h1").each((i, e) => {
        ct += `* [${e.innerHTML}](#${})\n`
    navigator.clipboard.writeText(ct += "***").then(function() {}, function(err) {

Script will use the navigator.clipboard API to insert Table of Contents code into clipboard. Read about it here.

Save the bookmark. Now you can go into Preview mode, click that bookmark, and you have the whole Table of Contents in your clipboard. All is left is go back to Write and paste!

Did you find it useful? Please let me know in the comments ๐Ÿ‘‡!

Did you find this article valuable?

Support Kamil Gierach-Pacanek by becoming a sponsor. Any amount is appreciated!