# DiscoTOC - automatic table of contents

**URL:** https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143
**Category:** Theme component
**Tags:** official, disco-toc
**Created:** [March 9, 2019, 5:36am UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143 "2019-03-09T05:36:22Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [March 9, 2019, 5:36am UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/1 "2019-03-09T05:36:22Z")

</div>

| | | |
| --- | --- | --- |
| :discourse2: | **Summary** | **DiscoTOC** will allow you to generate an interactive table of contents for your topics with one click! |
| 👓 | **Preview** | [Preview on Discourse Theme Creator](https://discourse.theme-creator.io/theme/Discourse/discotoc) |
| 🛠 | **Repository Link** | [https://github.com/discourse/DiscoTOC](https://github.com/discourse/DiscoTOC) |
| 📖 | **New to Discourse Themes?** | [Beginner’s guide to using Discourse Themes](https://meta.discourse.org/t/beginners-guide-to-using-discourse-themes/91966) |

Install this theme component

> [@](#):
>
> :discourse2: As this is an #official theme component maintained by the Discourse team, #Support, #Contribute > Bug, #Contribute > UX, and #Contribute > Feature requests can be made in the respective categories here on Meta, and tagged with the appropriate theme component tag. Click on a link below to get one started. 👍
> 
> [❓&nbsp; **Support**](https://meta.discourse.org/new-topic?category_id=6&tags=disco-toc "Ask for support on configuring and using DiscoTOC") [🐛&nbsp; **Bug**](https://meta.discourse.org/new-topic?category_id=1&tags=disco-toc "A bug report means something is broken, preventing normal/typical use of the theme component") [👀&nbsp; **UX**](https://meta.discourse.org/new-topic?category_id=9&tags=disco-toc "Discussion about the user interface of DiscoTOC, and how features are presented (including language and UI elements)") [💡&nbsp; **Feature**](https://meta.discourse.org/new-topic?category_id=2&tags=disco-toc "Discussion about how existing DiscoTOC features can be improved or enhanced, and how proposed new features could work")

### Samples

Desktop

 ![desktop](https://global.discourse-cdn.com/meta/original/3X/b/5/b5845b20dcc9d21535de6d86d24d85fa1120b8d3.png)

Mobile

 ![mobile](https://global.discourse-cdn.com/meta/original/3X/c/7/c7ff39471b4a9d5e093a4e99ff1a513497698ff6.png)

### Features

_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)

- Each toc entry links to the heading’s anchor, so you can also link to a specific section from another topic or post

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

- In topics with replies, a **Contents** / **Timeline** button lets readers switch between the toc and the normal topic timeline. The choice is remembered in the browser

- Works with the [Discourse Docs](https://meta.discourse.org/t/discourse-docs/144199) plugin

- Optional support for tocs in replies, not just the first post

- RTL support

### 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**.

```plaintext
# heading 1
## heading 2
### heading 3
#### heading 4
##### heading 5

```

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

```plaintext
# heading 2
## heading 3
## heading 3
### heading 4
## heading 3
# heading 2

etc...

```

A few things to know about which headings are compatible

- `h1` through `h5` are included. `h6` is not
- Headings inside quotes are ignored, so quotes won’t pollute the toc
- The toc only appears if the post has at least as many headings as the **TOC min heading** setting (3 by default)

### How do the links in the toc work?

Every heading in a cooked post gets an anchor in the form `p-<post id>-<heading slug>-<number>` — it’s the target behind the a heading. DiscoTOC links to those anchors rather than inventing its own.

Because those anchors include the heading’s position in the post, they change if you reorder or retitle headings. If you’re linking to sections from elsewhere, you can add stable named anchors above the heading:

```plaintext
<div><a name="my-section"></a></div>
## My section

```

Then link to `/t/your-topic-slug/1234#my-section`. Discourse allows `<a name="...">` in posts. DiscoTOC’s own entries will still use the core heading anchors, but yours will continue working regardless of edits.

### Settings

| Name | Description |
| --- | --- |
| minimum trust level to create TOC | The must have in order to see the TOC button in the composer |
| composer toc text | Text that appears at of the composer to indicate the topic will have a table of contents |
| auto TOC categories | Automatically enable categories |
| auto TOC tags | Automatically enable TOC on topics with these tags |
| enable TOC for replies | Allows TOC for replies. TOCs for replies are not affected by the **auto TOC tags** and **auto TOC categories** settings and must be inserted manually |
| TOC min heading | Minimum number of headings in a topic for the table of contents to be shown |

**composer toc text** is what shows up in the composer preview to indicate that a toc will be generated:

 ![composer-prompt](https://global.discourse-cdn.com/meta/original/3X/8/e/8e8582b406f1d3bba85ce280ae30e55eec68d88c.png)

### Translations

| Translation | Default |
| --- | --- |
| table\_of\_contents | table of contents |
| insert\_table\_of\_contents | Insert table of contents |
| jump\_bottom | Jump to end |
| toggle\_toc.show\_timeline | Timeline |
| toggle\_toc.show\_toc | Contents |

```plaintext
table_of_contents: "table of contents"

```

this is used for the button that opens the toc on mobile

 ![mobile-button](https://global.discourse-cdn.com/meta/original/3X/9/2/926572f91ea96e22eb74e9d9114ce772e4de1ebf.png)

```plaintext
insert_table_of_contents: "Insert table of contents"

```

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

 ![composer-button](https://global.discourse-cdn.com/meta/original/3X/f/6/f6a17663a6fa3c4b0bfd6ddc8564a0a58441445e.png)

```plaintext
toggle_toc.show_toc: "Contents"
toggle_toc.show_timeline: "Timeline"

```

these label the button that switches between the table of contents and the topic timeline

### How do I create a toc?

1. Write a topic with syntactically correct headings
2. Click the toc button in the composer gear menu. By default it only appears on the first post of a topic; enable the **enable TOC for replies** setting to use it in replies as well
3. Profit.

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

There’s no space to show both at the same time, so in a topic with a toc the topic progress widget is hidden while you’re on the first post, and you see the toc instead. Once you scroll past the first post, the toc is replaced by the regular topic progress widget while you read replies. (With **enable TOC for replies** on, a reply that has its own toc shows that one instead.)

In topics with more than one post, a **Contents** / **Timeline** button lets readers switch between the two, and the preference is remembered in their browser.

On narrow screens the toc opens as an overlay via a button in the topic progress area.

### Are there any downsides to using this component?

Almost everything happens client-side, so you can remove the component at any time and your posts will render as they did before. The one thing that touches your content is the composer button: it wraps the post in a `<div data-theme-toc="true">` marker, which is how the component knows the post should have a toc. If you uninstall the component, that wrapper stays in the post but has no visible effect.

### Limitations

`h6` headings and headings inside quotes are not included in the toc.

#### Credit

This started as a hard fork of Greg Franko’s [tocify.js](http://gregfranko.com/jquery.tocify.js/) library, and has since been rewritten as native Ember components. There are no external dependencies or requests.

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

> :discourse2: **Hosted by us?** Theme components are available to use on our Pro, Business and Enterprise plans.

> Last edited by @awesomerobot 2026-07-27T16:04:08Z
> 
> > **Check document**
> >
> > Perform check on document:

---

<div class="post-metadata">

### Author: ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)
#### Post date: [August 23, 2023, 2:52pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/214 "2023-08-23T14:52:28Z")

</div>

4 posts were split to a new topic: [How to move the TOC to the left side of the post?](https://meta.discourse.org/t/how-to-move-the-toc-to-the-left-side-of-the-post/276309)

---

<div class="post-metadata">

### Author: ![mentalstring](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mentalstring/32/168934_2.png) [@mentalstring](https://meta.discourse.org/u/mentalstring)
#### Post date: [September 27, 2020, 7:52am UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/235 "2020-09-27T07:52:37Z")

</div>

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.

> [@tobiaseigen](#):
>
> So displaying both at the same time is a bit unwieldy.

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.

---

<div class="post-metadata">

### Author: ![AndyB](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/andyb/32/223836_2.png) [@AndyB](https://meta.discourse.org/u/AndyB)
#### Post date: [May 21, 2021, 2:03pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/269 "2021-05-21T14:03:34Z")

</div>

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](https://global.discourse-cdn.com/meta/original/3X/0/7/077cdb19632473ba429cfe13e8432400fac21566.png "Performance and Stability example")

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.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [May 21, 2021, 8:22pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/270 "2021-05-21T20:22:58Z")

</div>

> [@AndyB](#):
>
> We recently installed DiscoTOC for our forums and were wondering if it’s possible to get the component to read alt text in images?

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.

---

<div class="post-metadata">

### Author: ![AndyB](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/andyb/32/223836_2.png) [@AndyB](https://meta.discourse.org/u/AndyB)
#### Post date: [May 23, 2021, 9:14pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/271 "2021-05-23T21:14:21Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![TheOctopus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/theoctopus/32/205017_2.png) [@TheOctopus](https://meta.discourse.org/u/TheOctopus)
#### Post date: [July 18, 2021, 9:34pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/273 "2021-07-18T21:34:33Z")

</div>

The heading anchor functionality on this component slightly conflicts with the _Automatic header links_ functionality [added in 2.7.0beta6](https://meta.discourse.org/t/2-7-0-beta6-automatic-group-avatar-flair-improved-user-education-content-bookmark-pinning-and-more/185908#automatic-header-anchor-links), since headings get two icons on hover, one from Discourse and one from DiscoTOC. Is there a way round this?

---

<div class="post-metadata">

### Author: ![Don](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/don/32/228726_2.png) [@Don](https://meta.discourse.org/u/Don)
#### Post date: [July 18, 2021, 9:43pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/274 "2021-07-18T21:43:22Z")

</div>

Hello,

You can hide the _Automatic header links_ anchor with

```plaintext
.anchor {
  display: none;
}

```

---

<div class="post-metadata">

### Author: ![neo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neo/32/156675_2.png) [@neo](https://meta.discourse.org/u/neo)
#### Post date: [July 21, 2021, 7:41pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/275 "2021-07-21T19:41:46Z")

</div>

Hi dodesz,

I made the post width much larger than the default one, and after install this component it looks something wrong, could you tell me how to fix this problem?

❤ thanks!

 ![Selection_839](https://global.discourse-cdn.com/meta/original/3X/3/f/3f5494e73697ef8fd73c9262519372316b28aa2a.jpeg)

---

<div class="post-metadata">

### Author: ![fkohrt](https://avatars.discourse-cdn.com/v4/letter/f/6de8d8/32.png) [@fkohrt](https://meta.discourse.org/u/fkohrt)
#### Post date: [August 27, 2021, 9:11am UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/276 "2021-08-27T09:11:04Z")

</div>

On a forum running Discourse 2.8.0.beta4 ([90232af778](https://github.com/discourse/discourse/commits/90232af7788f5b9c0d69c47f80c0564275a54060)), including the DiscoTOC component leads to an error message:

 ![oops](https://global.discourse-cdn.com/meta/original/3X/a/1/a1d1e80cb385cc742b80cb3b60c6bd8f88a34784.png)

The component had been activated before and raised an issue with the previously installed Discourse version as well, although I cannot say which version that was.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [August 27, 2021, 4:44pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/277 "2021-08-27T16:44:22Z")

</div>

Are you able to find any error messages related to the issue in your site’s error logs?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [August 27, 2021, 4:50pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/278 "2021-08-27T16:50:23Z")

</div>

That error message is a backend error, while DiscoTOC is a front-end theme-component so it’s hard for those to be related. Do you have any plugins installed?

---

<div class="post-metadata">

### Author: ![fkohrt](https://avatars.discourse-cdn.com/v4/letter/f/6de8d8/32.png) [@fkohrt](https://meta.discourse.org/u/fkohrt)
#### Post date: [August 31, 2021, 6:33am UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/279 "2021-08-31T06:33:06Z")

</div>

> [@simon](#):
>
> Are you able to find any error messages related to the issue in your site’s error logs?

Unfortunately, I couldn’t find anything useful in the `/logs`.

> [@Falco](#):
>
> Do you have any plugins installed?

I do, here’s the relevant excerpt from `app.yml`:

```yml
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-openid-connect.git
          - git clone https://github.com/discourse/discourse-checklist.git
          - git clone https://github.com/discourse/discourse-push-notifications.git
          - git clone https://github.com/discourse/discourse-characters-required.git
          - git clone https://github.com/angusmcleod/discourse-news.git
          - git clone https://github.com/discourse/discourse-data-explorer.git
          - git clone https://github.com/DNOeV/discourse-watch-category.git
          - git clone https://github.com/discourse/discourse-footnote.git
          - git clone https://github.com/discourse/discourse-knowledge-explorer.git

```

---

<div class="post-metadata">

### Author: ![debryc](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/debryc/32/101652_2.png) [@debryc](https://meta.discourse.org/u/debryc)
#### Post date: [September 3, 2021, 8:58pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/280 "2021-09-03T20:58:48Z")

</div>

When a header is within a quote, the header doesn’t show up in the TOC. Could this behavior be changed?

> # This header won’t show up in TOC
> 
> Quoted content

# This header DOES show up in TOC

> Quoted content

---

<div class="post-metadata">

### Author: ![Jagster](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagster/32/192154_2.png) [@Jagster](https://meta.discourse.org/u/Jagster)
#### Post date: [September 3, 2021, 9:12pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/281 "2021-09-03T21:12:31Z")

</div>

I don’t know how it is planned to work but normally no because it’s part of quote, not a heading of that text.

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [September 3, 2021, 9:42pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/282 "2021-09-03T21:42:48Z")

</div>

Could you try using the html \<blockquote\> instead? That would allow the header # to be at the start of a line.

Eg:

```plaintext
<blockquote>

### Anchor Header

</blockquote>

```

> ### Anchor Header

I’ve not tried it in a TOC, but it seems to work with the auto-anchor-headers in a regular post.

---

<div class="post-metadata">

### Author: ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)
#### Post date: [September 4, 2021, 4:18pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/283 "2021-09-04T16:18:05Z")

</div>

Why do you want headers within quotes to show up in the TOC? What’s your use case?

---

<div class="post-metadata">

### Author: ![debryc](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/debryc/32/101652_2.png) [@debryc](https://meta.discourse.org/u/debryc)
#### Post date: [September 8, 2021, 9:54pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/284 "2021-09-08T21:54:30Z")

</div>

> [@JammyDodger](#):
>
> Could you try using the html
> 
> > instead? That would allow the header # to be at the start of a line.

Thank you for the idea. It didn’t work for me, though.

> [@tobiaseigen](#):
>
> Why do you want headers within quotes to show up in the TOC? What’s your use case?

Here’s an example of when I use quotes to visually structure content starting under Issue Area: Age

> **[A Progressive's Style Guide: Toward Harnessing Language in Support of...](https://hub.youthpowercoalition.org/t/a-progressives-style-guide-toward-harnessing-language-in-support-of-intersectionality-and-cross-sector-power-building/285)**
>
> Caption: Cover art of A Progressive’s Style Guide by Hanna Thomas (SumOfUs.org) and Anna Hirsch (ActivistEditor.com), which shows the faces of people from diverse backgrounds and identities. Downloadable Guide Guide Excerpts Introduction ...

---

<div class="post-metadata">

### Author: ![Jagster](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagster/32/192154_2.png) [@Jagster](https://meta.discourse.org/u/Jagster)
#### Post date: [September 8, 2021, 10:08pm UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/285 "2021-09-08T22:08:33Z")

</div>

Why are you using quoting like that? Telling source is enough. Plus grammatically that is wrong, in english too.

---

<div class="post-metadata">

### Author: ![Jagster](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagster/32/192154_2.png) [@Jagster](https://meta.discourse.org/u/Jagster)
#### Post date: [September 20, 2021, 7:36am UTC](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143/287 "2021-09-20T07:36:08Z")

</div>

Is this a bug or just another user, but… how should I close the TOC? I was looking for some basic instructions how an enduser should use private messages and of course I went to new users doc and opened the TOC to see if there is some info.

I was using iPad and DiscourseHub.

I got this:

 ![kuva](https://global.discourse-cdn.com/meta/original/3X/c/b/cbe396a0e8f096358bb91cf2c473f83ddca93bbc.png)

The TOC is just fine. But it is overlapping text and I coudn’t get is suppress back. So what the heck I did wrong, or didn’t at all 🥺

[Next page](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143.md?page=2)
