# How we built the new Table of Contents feature

DevFeed: [How we built the new Table of Contents feature](<https://devfeed.tech/articles/how-we-built-the-new-table-of-contents-feature-20320.md>)

Original publisher: [Read original article](<https://medium.engineering/how-we-built-the-new-table-of-contents-feature-c3825d8c279d?source=rss----2817475205d3---4>)

Author: Scott Batson

Published: 2026-07-23T14:28:55Z

Content type: article

Language: en

Sources: [Medium](<https://devfeed.tech/sources/medium.md>)

Topics: [Chrome extension](<https://devfeed.tech/topics/chrome-extension.md>), [data](<https://devfeed.tech/topics/data.md>), [Usability](<https://devfeed.tech/topics/usability.md>), [Code](<https://devfeed.tech/topics/code.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [chrome-extension](<https://devfeed.tech/tags/chrome-extension.md>), [code](<https://devfeed.tech/tags/code.md>), [extension](<https://devfeed.tech/tags/extension.md>), [feature](<https://devfeed.tech/tags/feature.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [programming](<https://devfeed.tech/tags/programming.md>), [software-development](<https://devfeed.tech/tags/software-development.md>), [software-engineering](<https://devfeed.tech/tags/software-engineering.md>), [usability](<https://devfeed.tech/tags/usability.md>), [web-development](<https://devfeed.tech/tags/web-development.md>)

## AI overview

The article explains how Medium built a dynamic Table of Contents feature for its editor. It compares the approach of an existing Chrome extension, which inserts a static list into a post, with Medium's approach of generating the table of contents from the post body at render time so revisions remain reflected automatically.

## Source excerpt

How a feature goes from idea to prototype to shipped For years, there's been this really popular Chrome extension for adding a table of contents to your Medium stories. Props to Vinicius De Antoni for writing a popular chrome extension all those years go. The extension was so popular, we even wrote about it in our Medium Handbook. How to make a table of contents for your Medium story The fact that it was so popular was a signal to me. There was a decent size of our user base that wanted this feature. So, at first I set out to just copy it. The Chrome extension extends the popup menu we have in the editor to add a new option. Just a styled button on the existing list. const inject = () => { const tooltipToggleMenu = document.querySelector( "[data-action=inline-menu]", ); const tooltip = document.querySelector(".inlineTooltip"); const tooltipMenu = document.querySelector(".inlineTooltip-menu"); const addEmbedButton = document.querySelector( ".inlineTooltip-menu [title='Add an embed']", ); if (!tooltip || !tooltipToggleMenu || !tooltipMenu || !addEmbedButton) { return; } tooltip.style.width = "auto"; const toCButton = document.querySelector("[data-action='inline-menu-toc']"); if (toCButton) { return; } const handleAddToCClick = (e) => { const container = document.querySelector(".is-selected"); tooltipToggleMenu.click(); container.innerHTML = generate().join("
"); setTimeout(() => { simulateKeydown(container, 13); }, 0); }; const addToCButton = addEmbedButton.cloneNode(true); const title = "Add a Table of Contents"; addToCButton.setAttribute("title", title); addToCButton.setAttribute("aria-label", title); addToCButton.setAttribute("data-action", "inline-menu-toc"); addToCButton.setAttribute( "data-action-value", "Generate a table of contents", ); addToCButton.setAttribute("data-default-value", "Table of contents"); addToCButton.innerHTML = "⋮"; addToCButton.style.color = "rgb(26, 137, 23)"; addToCButton.style.border = "1px solid"; addToCButton.style.fontWeight = "bo