DiscoTOC - automatic table of contents

:discourse2: Summary DiscoTOC will allow you to generate an interactive table of contents for your topics with one click!
:eyeglasses: Preview Beginner's guide to using Discourse Themes (open it in a new tab)
:hammer_and_wrench: Repository Link https://github.com/discourse/DiscoTOC
:open_book: New to Discourse Themes? Beginner’s guide to using Discourse Themes

Install this theme component





toc = table of contents

  • Automatically generates the entire toc via a button in the composer gear menu

  • The toc will always be on the screen - scrolls with content like the topic progress widget

  • As you scroll past sections in the topic, the active element in the table of contents will be set to active (blue highlight)

  • adds id attributes to headings (you can link to a specific section from another topic / post)

  • clicking on any link in the toc will instruct the browser to navigate to relevant section (smooth-scrolling)

  • adds a copy-able link next to each heading (if you want to link to it)

  • RTL support

  • The colors are based on your current active color palette

How does it work?

In a nutshell, it looks for headings in topics which are marked to have a toc (via the composer button) and if it turns out the current topic is marked, then it takes all the headings and puts them in the toc (nested in order of heading levels) - this means that your markdown must be syntactically correct.

# heading 1
## heading 2
### heading 3
#### heading 4
##### heading 5
###### heading 6

You’re free to go back and fourth in heading levels, but the order must be correct

# heading 2 
## heading 3
## heading 3
### heading 4
## heading 3
# heading 2


In order for the links in the toc to work, headings must have id attributes. The component will check if the headings already have ids and if they do, then they are respected. This is handy if you ever manually created a toc.

If the headings don’t have ids, then it will generate an id for each heading based on its text (unwanted characters are stripped out)

once all of that is done, it will also add a link next to each button that links directly to that section:


This theme only comes with one setting, the toc icon. (used to add the icon to the subset and I don’t recommend changing it.


The theme comes with three strings that you can translate or change.

table_of_contents: "table of contents"

this used for the button that opens the toc on mobile

insert_table_of_contents: "Insert table of contents"

this is used as the text for the toc button in the composer gear menu

topic_will_contain_a_table_of_contents: "This topic will contain a table of contents"

This is the text that shows up in the composer preview to indicate that the a toc will be generated for the topic

How do I create a toc?

  1. Write a topic with syntactically correct headings
  2. Click the toc button in the gear menu (only shows up when creating a regular topic - replies and PMs are ignored
  3. Profit.

What happens to the topic progress widget when a topic has a toc?

As you can probably guess, there’s no space to show both at the same time, so the way this component works is as follows

in a topic with a toc, the topic progress widget is hidden while the first post is on screen, and you see the toc instead.

Once you scroll past the first post, the toc will not scroll with you and the topic progress will be shown instead while you read any replies.

So, first posts get the toc, and subsequent posts get the regular topic progress widget.

The happens on both desktop and mobile.

Are there any downsides to using this component?

Nothing I am aware of, all the changes are done on the client-side. So you can easily remove the component and your posts would go back to the way they were before you installed it.


This component assumes the standard topic layout. As such, it won’t work with themes that modify that layout such as the Vincent theme. Support for popular themes that modify the layout will come at a later stage in the form of component settings.


I started with Greg Franko’s tocify.js library. However, it looks like it’s not been updated in a while, so this is essentially a hard-fork that removes a lot of unnecessary features, integrates and styles the rest for Discourse.

So, there are no external requests and the total size is ~ 4kb gzip.

Big thanks to @erlend_sh for lots of valuable feedback and to @david for his help with translations.


  • live composer preview of toc content (might be too expensive)
  • support for popular themes that alter topic layout
  • clicking links next to headings will copy to clipboard automatically

This is a very early release, if you spot any problems or have ideas for improvement, please let me know.


Is there a way to move the TOC to the left side of the post, rather than the default right side?

1 Like

I’ve also been trying to figure this out. It’s nice to be distinctive, but table of contents are almost always on the left side of sites, which makes sense given that we read left to right. Is there a way to do this?

1 Like

How can we keep the table of contents on the left and keep the standard discord scrollbar on the right? I have some difficulty getting to the bottom of a post since the scrollbar has changed.

Here is an example:


Hello AntiMetaman,

You can change the direction with css. Add something like this to desktop css section. It should show the DiscoTOC on the left side.

.d-toc-post .d-toc-article{
    flex-flow: row-reverse;

I don’t know how this component is implemented or much about the frontend structure of Discourse, so I can only throw in a guess.

Couldn’t the progress bar only be shown a) if more than 1 post in the topic and b) adjust its start to be from the 2nd post (instead of 3rd), but also c) add some comfortable bottom/top margin to one of the two elements to make sure the other remains distant enough (eg 1vh) as to not make it strange looking?

In other words, instead of using the whole 2nd post as a gap, use CSS to allow some room between them (iff there’s more than 1 post).

Again, this might not make any sense at all as I don’t know much about the way this is working atm.


I am wondering how the TOC plugin is intended to function as I am finding its behaviour sort of odd. I have attached an animated gif below showing my observed behaviour. Is this intentional?

My personal thought/preference is that the TOC is just fully expanded from the start.

Thanks in advance!


I am bumping this in hopes that someone will comment on the above functionality.

Is this functionality as intended? Am I doing something wrong? Is there a possibility to get the option to set the TOC to be fully expanded and static?

Thanks in advance!


Is there a plan, that the TOC is also visible for published pages? Page publishing was a feature introduced in discourse 2.5? This would be a huge benefit of this theme component!


I checked it with non-Latin symbols like Cyrillic and it’s not working. When I copy the url of the subheader and try to follow the link - the TOC is not working (the page opens, but doesn’t move to the subheader). How can it be solved?

1 Like

Another question. I added extra div to the post. Now it looks like this:

<div data-theme-toc="true"> </div>
<div data-theme-profile="manual">
## Chapter 1
## Chapter 2

But the TOC is not visible in this case. How can it be fixed?


Hi, I noticed an odd interaction with DiscoTOC and Slack integration. Basically the header links don’t properly post.

See details here


That is because the heading links do not include the path to the topic. For example <a name="overview" href="#overview">. The Chat Integration plugin is attempting to convert relative links into absolute links by prepending the forum’s root URL to any links in the post, but that is not going to work for the header links because the path to the topic is missing.

A possible solution would be for us to add the path to the topic to the TOC href element. For example, instead of setting <a name="overview" href="#overview">, the href element would be set to something like /t/your-topic-slug/1234#overview".



How I can add into all my existing post the toc ?
I don’t want add this manually :slight_smile:
Perhaps with rake post ?




Is there any way to make the entire TOC show up at once instead of dynamically hiding most of it? A full post outline can be useful for finding a section without knowing and clicking through its ancestry, or so you can just read all the section names as a way to skim a post.


Hi there! We recently installed DiscoTOC for our forums and were wondering if it’s possible to get the component to read alt text in images? We’ve used images for some patch note headers…

like so:
Performance and Stability

And unfortunately the TOC system doesn’t seem to be able to parse an image as a header, creating a blank entry on the list and creating a link that takes you to a blank page. Is there any workaround for this beyond “don’t use images”? Thank you! Love the system otherwise.

1 Like

My guess is that the solution is to not use images as headings, but possibly there will be a way to get it to work by adding some code to your site that hooks into the DiscoTOC code. Whether or not it’s worth looking into that will depend on how important it is for you to use images in the post’s headings.


We’ve been using images as headers in our patch notes consistently for quite some time now, and it’s a part of our branding and presentation; not just on the forums, but on Steam and such as well. We would like to have the ability to continue using images as headers while using DiscoTOC in order to remain consistent.

DiscoTOC has been great for other things such as for an AMA recap, a megapost about our dedicated server launcher app, new player guides, etc. We like the system a lot, but would love for a little extra functionality for the way we present patch notes.

1 Like

I would second this feature request. I can see that this might result in long TOCs, but at least one could add an “expand all” button or Link?


The heading anchor functionality on this component slightly conflicts with the Automatic header links functionality added in 2.7.0beta6, since headings get two icons on hover, one from Discourse and one from DiscoTOC. Is there a way round this?

1 Like