# Table of Contents Tutorial for Casper Version 4 - Simplified

**URL:** <https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584>\
**Category:** Themes\
**Created:** [May 9, 2021, 8:15pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584 "2021-05-09T20:15:07Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![JustinCEO](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/justinceo/32/13232_2.png) [@JustinCEO](https://forum.ghost.org/u/JustinCEO)\
**Post date:** [May 9, 2021, 8:15pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/1 "2021-05-09T20:15:07Z")

</div>

I’d like to have tables of contents autogenerated on my posts. Fancier stuff like a ToC that “floats” persistently along the side of the page would be nice, but I’m okay with something more basic like a simple ToC at the top of the page before the content.

I’m curious if anyone has a very recent table of contents tutorial that’s been done with recent releases of Casper (I just installed Ghost so I’m running the latest everything). I looked at a bunch of existing ones, but my web skills are pretty weak so I need something very hand-holdy and on point, and I seem to keep running into issues where something’s wonky, possibly cuz of some changes in Casper since a given tutorial was made (initially the issue was that class names had been changed and so the code I was pasting in wasn’t even looking for the right thing. Figured that out, but then I had issues with the alignment of the ToC being wonky and uncentered or other annoyances).

If you have paid/subscriber-only content that’s on point to this request and want to link that, don’t be shy, i’ll consider it 🙂

---

<div class="post-metadata">

**Author:** ![DonaldH](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/donaldh/32/13880_2.png) [@DonaldH](https://forum.ghost.org/u/DonaldH)\
**Post date:** [May 10, 2021, 12:03am UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/2 "2021-05-10T00:03:06Z")

</div>

> I’d like to have tables of contents autogenerated on my posts. Fancier stuff like a ToC that “floats” persistently along the side of the page would be nice, but I’m okay with something more basic like a simple ToC at the top of the page before the content.  
> I’m curious if anyone has a very recent table of contents tutorial that’s been done with recent releases of Casper (I just installed Ghost so I’m running the latest everything).

I would like this as well.

And welcome to the Ghost forum, Justin 🙂

---

<div class="post-metadata">

**Author:** ![DonaldH](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/donaldh/32/13880_2.png) [@DonaldH](https://forum.ghost.org/u/DonaldH)\
**Post date:** [May 10, 2021, 12:09am UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/3 "2021-05-10T00:09:01Z")

</div>

Also I think somebody else will probably respond, but if they don’t, I’ll have a go at building this and then share the code with you. I’m certainly not the most experienced or skilled developer here but I have implemented exactly this on a non-Ghost website before and I can’t imagine it will be much more difficult.

---

<div class="post-metadata">

**Author:** ![JustinCEO](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/justinceo/32/13232_2.png) [@JustinCEO](https://forum.ghost.org/u/JustinCEO)\
**Post date:** [May 10, 2021, 2:54am UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/4 "2021-05-10T02:54:49Z")

</div>

ok through trial and error i’ve managed to get something kinda working here  
My approach is heavily based on this guy’s post:

> **[Adding a table of contents to a Ghost blog](https://www.wafrat.com/adding-a-table-of-contents-to-a-ghost-blog/)**
>
> I recently needed to add a table of contents to my blog post to make it more browsable. To my surprise, there was no built-in way to do it in Ghost, and the solutions on the internet range from terrible to nice and clean. If you're only interested in...

you can see an example at this test page [https://blog.justinmallone.com/simply-scheme-chapter-23-vectors/](https://blog.justinmallone.com/simply-scheme-chapter-23-vectors/) (i pasted some content from my old blog to test the ToC aspect)

 ![image](https://us1.discourse-cdn.com/flex015/uploads/ghost2/original/2X/c/cb25889fd363083cf34a62436134c3bbb002bf55.png)  
(The numbering is a numbering of exercises rom the headings, to be clear - that’s not automatic numbering coming from an ordered list - i suppressed displaying those).

Ok so my current method requires manually dropping something into an html block where you want the TOC to display. So it’s not automatic, but OTOH this does have the virtue of letting you choose if you want to display a TOC.

So you just pop one of these into an HTML block in the post you want a ToC for:

```
<div class="hc-toc"></div>

```

and then i’ve got this mess in the Site Footer in Code Injection to actually get everything working:

```
<!-- table of contents -->

<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.min.js" integrity="sha384-TnuMTlegqfBi40E9e3dO2qfmPVKDjLFCCgyZ5bR3SA/hYTJXI090bTbAr/AXO+bc" crossorigin="anonymous"></script>

<script>
tocbot.init({
// Where to render the table of contents.
tocSelector: '.hc-toc',
// Where to grab the headings to build the table of contents.
contentSelector: '.gh-content',
// Which headings to grab inside of the contentSelector element.
headingSelector: 'h1, h2, h3, h4, h5, h6' ,
// For headings inside relative or absolute positioned containers within content.
hasInnerContainers: true,
});

</script>

<!-- styling background of toc -->

<style>
.hc-toc {
  border: 1px solid #a2a9b1;
  background-color: #f8f9fa;
  padding: 5px;
}
</style>

<!-- Contents text above TOC entries -->
<style>
.hc-toc::before {
  content: "Table of Contents";
  display: flex;
  justify-content: left;
  font-weight: bold;
  margin-left: 10px;
}
</style>

<style>
.hc-toc ol {
   /* Move bullets inside. Applies to both first and second level list items. */
  list-style-position: inside;
  /* Cancel out Ghost's default margin-bottom: 30px. */
  margin-bottom: 0;
    list-style: none;
}
   .hc-toc li {
    /* shrink line height */
   line-height:80% ;
    }
</style)

```

key thing seems to be to select `gh-content` and not `post-content` or `post-full-content` like you may find other guides suggesting, at least if you’re on the latest Casper.

Some next steps are tweaking the styling a bit more (changing it from hyperlink blue, say) and seeing if I can get it to work with dark mode. I tried dark mode but it was a mess, will follow up later with specifics but it’s late here 🙂

---

<div class="post-metadata">

**Author:** ![denvergeeks](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/denvergeeks/32/7401_2.png) [@denvergeeks](https://forum.ghost.org/u/denvergeeks)\
**Post date:** [May 10, 2021, 2:59am UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/5 "2021-05-10T02:59:02Z")

</div>

**TO ADD A TOC (Table of Contents) IN THE CASPER THEME …**

**1. Paste this into your Site Header Code Injection** …

> ```
> <!-- Tocbot Stylesheet -->
> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.10.0/tocbot.css" />
> 
> <!-- Tocbot Inline CSS (Specific Adjustments for the Casper Theme) -->
> <style>
> /* Offset headings from fixed header */
> .post-content h2::before,
> .post-content h3::before {
> display: block;
> content: " ";
> height: 84px;
> margin-top: -84px;
> visibility: hidden;
> }
> 
> /* Adjust content wrapper */
> .post-content {
> display: block;
> }
> 
> /* Adjustments to wide and full width cards */
> .kg-gallery-card,
> .kg-width-wide,
> .kg-width-full {
> display: flex;
> flex-direction: column;
> align-items: center;
> }
> 
> .kg-gallery-card > *,
> .kg-width-wide > *,
> .kg-width-full > *,
> figure.kg-width-full img {
> margin-left: -50vw;
> margin-right: -50vw;
> }
> 
> .post-full-content pre {
> max-width: 0;
> }
> 
> /* Add a light gray box (Optional) */
> .toc {
> border: 1px solid #a2a9b1;
> background-color: #f8f9fa;
> padding: 5px;
> }
> </style>
> 
> ```

**2. Paste this into your Site Footer Code Injection** …

> ```
> <!-- Tocbot Script -->
> <script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.10.0/tocbot.min.js"></script>
> <script>
> tocbot.init({
> tocSelector: '.toc',
> contentSelector: 'section.gh-content.gh-canvas',
> hasInnerContainers: true
> });
> </script>
> 
> ```

**3. Paste this HTML snippet where you want the Table of Contents to appear** …

> ```
> <aside class="toc"></aside>
> 
> ```

**4. For quick testing, you can navigate to a post (one with some headings) in Ghost admin** and create a new HTML card in the area you want your table of contents to appear. A HTML card can be added using the “ **+** ” button or by typing “/HTML” and hitting enter.

 ![HTML card being highlighted in card options](https://us1.discourse-cdn.com/flex015/uploads/ghost2/original/2X/e/e399a77929cf576b8dae3a20e9559521e5d99d39.png)

Within the HTML card paste the HTML snippet:

> ```
> <aside class="toc"></aside>
> 
> ```

Then click save and view the post. The snippet you’ve added to the post should now contain a table of contents created from all the headings in that post 🙌.

**5. To get the TOC working on all of your site’s post and/or pages** , paste the HTML snippet in your post.hbs and/or in page.hbs, or in any other template where you want the TOC to appear for every post and/or page.

---

<div class="post-metadata">

**Author:** ![denvergeeks](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/denvergeeks/32/7401_2.png) [@denvergeeks](https://forum.ghost.org/u/denvergeeks)\
**Post date:** [May 10, 2021, 4:20am UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/6 "2021-05-10T04:20:33Z")

</div>

**FOR A FIXED POSITION TOC** …

**Add this CSS also in between the style tags in the Site Header Code Injection** …

> ```
> /* Top Right Fixed position TOC (Optional) */
> .toc {
> position: fixed;
> top: 54px;
> right: 0;
> }
> 
> ```

… since this is going to fix the TOC in a static position, it doesn’t matter where (within either the post.hbs, page.hbs, or inserted into the post editor using an HTML card) you put this snippet.

**FOR A FIXED POSITION TOC IN A COLLAPSIBLE ACCORDION** …

**1. Add this CSS in between the style tags in the Site Header Code Injection** …

> ```
> /* Fixed position and simple styling for accordion container (Optional) */
> details {
> position: fixed;
> top: 54px;
> right: 0;
> cursor: pointer;
> z-index: 100;
> }
> summary {
> background-color: navy;
> color: #fff;
> padding-left: 10px;
> padding-bottom: 3px;
> padding-right: 20px;
> }
> 
> ```

**2. Wrap the HTML snippet as below** …

… replacing this HTML snippet …

> ```
> <aside class="toc"></aside>
> 
> ```

… and instead pasting this HTML snippet …

> ```
> <details open>
> <summary>&nbsp;Page Contents</summary>
> <aside class="toc"></aside>
> </details>
> 
> ```

… since this is going to fix the TOC accordion in a static position, it doesn’t matter where (within either the post.hbs, page.hbs, or inserted into the post editor using an HTML card) you put this snippet.

**You can also make the accordion open or closed by default** …

> `<details open>`

… makes the TOC accordion open by default …

> `<details>`

… makes the TOC accordion closed by default …

---

<div class="post-metadata">

**Author:** ![JustinCEO](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/justinceo/32/13232_2.png) [@JustinCEO](https://forum.ghost.org/u/JustinCEO)\
**Post date:** [May 10, 2021, 1:27pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/7 "2021-05-10T13:27:04Z")

</div>

thank you so much @denvergeeks! This looks really on point. I’m going to play with some of this later 🙂 I see that you use details and summary tags to make the TOC collapsible, which is a really great and simple solution 🙂

---

<div class="post-metadata">

**Author:** ![DonaldH](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/donaldh/32/13880_2.png) [@DonaldH](https://forum.ghost.org/u/DonaldH)\
**Post date:** [May 10, 2021, 3:33pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/8 "2021-05-10T15:33:58Z")

</div>

> [@denvergeeks](#):
>
> `<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.10.0/tocbot.css" />`

This is great! Is there a way to exclude the H1 (the title of the page) from the table of contents?

---

<div class="post-metadata">

**Author:** ![DonaldH](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/donaldh/32/13880_2.png) [@DonaldH](https://forum.ghost.org/u/DonaldH)\
**Post date:** [May 10, 2021, 3:40pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/9 "2021-05-10T15:40:06Z")

</div>

The only problem I can see with the fixed position TOC is that it’s going to be in front of and obscure the main post content on small screens like phones.

Would a media query be the best solution to having the TOC fixed to the side on larger screens but return to the original position at the top of the blog post on smaller screens?

And is there a simple way to remove the numerals from the TOC? Or change them to roman numerals?

---

<div class="post-metadata">

**Author:** ![JustinCEO](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/justinceo/32/13232_2.png) [@JustinCEO](https://forum.ghost.org/u/JustinCEO)\
**Post date:** [May 10, 2021, 3:57pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/10 "2021-05-10T15:57:18Z")

</div>

good point real: small screens. I don’t know the answer re: best solution for handling that.

re: removing the numerals, I’m styling the ordered list within the toc with:

```
    list-style: none;

```

and that does it

---

<div class="post-metadata">

**Author:** ![DonaldH](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/donaldh/32/13880_2.png) [@DonaldH](https://forum.ghost.org/u/DonaldH)\
**Post date:** [May 10, 2021, 4:11pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/11 "2021-05-10T16:11:40Z")

</div>

@media only screen and (min-width: 1400px) {  
.toc {  
position: fixed;  
top: 54px;  
right: 0;  
}  
}

This should work I think.

Now I just have to figure out how to exclude the h1 from the list.

---

<div class="post-metadata">

**Author:** ![JustinCEO](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/justinceo/32/13232_2.png) [@JustinCEO](https://forum.ghost.org/u/JustinCEO)\
**Post date:** [May 10, 2021, 4:50pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/12 "2021-05-10T16:50:38Z")

</div>

> [@DonaldH](#):
>
> @media only screen and (min-width: 1400px) {  
> .toc {  
> position: fixed;  
> top: 54px;  
> right: 0;  
> }  
> }
> 
> This should work I think.

Worked for me 🎉

---

<div class="post-metadata">

**Author:** ![denvergeeks](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/denvergeeks/32/7401_2.png) [@denvergeeks](https://forum.ghost.org/u/denvergeeks)\
**Post date:** [May 10, 2021, 7:49pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/13 "2021-05-10T19:49:02Z")

</div>

**TO EXCLUDE H1 (POST/PAGE TITLE) FROM THE TOC** …

(From [Tocbot](https://tscanlin.github.io/tocbot/#usage) Docs)

 ![tocbot-heading-selectors](https://us1.discourse-cdn.com/flex015/uploads/ghost2/original/2X/a/a58c2d34c024cf076fda1a03e8c0e5f22f68ec80.jpeg)

**So change your Footer Code Injection to** …

> ```
> <!-- Tocbot Script -->
> <script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.10.0/tocbot.min.js"></script>
> <script>
> tocbot.init({
> tocSelector: '.toc',
> contentSelector: 'section.gh-content.gh-canvas',
> headingSelector: 'h2, h3',
> hasInnerContainers: true
> });
> </script>
> 
> ```

---

<div class="post-metadata">

**Author:** ![JavowiecPL](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/javowiecpl/32/25482_2.png) [@JavowiecPL](https://forum.ghost.org/u/JavowiecPL)\
**Post date:** [May 11, 2021, 12:41am UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/14 "2021-05-11T00:41:54Z")

</div>

## Ghost 4.0 issue

It seems that after this change:

> <https://github.com/TryGhost/Ghost/issues/12646>
>
> We want the ability to make changes in our rendered HTML output without breaking… old content. An example of such a change in 4.0 will be modifying header elements' \`id\` attribute value to better serve non-English languages. If we were to make that change without considering old content then any time old content is re-rendered (through editing old posts, or forced re-render in a major upgrade) then deep-links could break from \`id\` attributes adopting the newer scheme.
> 
> By introducing the concept of "Ghost version" to our mobiledoc (separate to the underlying mobiledoc spec version) we can use it in our card renderers and post-render modifiers to change the output in new content without breaking the old.
> 
> We also want to remove the outdated/deprecated markdown card alias (Ghost 1.0 had a different name for markdown cards) and the custom card-only version that was added to facilitate adding the 1.0 wrapper element. This is a cleanup task.
> 
> \- \[x\] Test \`mobiledoc-kit\` and \`mobiledoc-dom-renderer\` to make sure there are no problems adding top-level properties to mobiledoc documents
> \- \[x\] Decide on versioning scheme
> - tied to Ghost major or separate so we can modify HTML output without breaking changes outside of major releases?
> \- \[x\] Migration to modify mobiledoc of all posts
> - \[x\] add a \`ghostVersion\` property to mobiledoc of all posts
> - \[x\] change markdown card names from \`card-markdown\` to \`markdown\` (cleanup of 1.0 content)
> \- \[x\] Ensure newer \`ghostVersion\` is set for all newly created mobiledoc (Ghost + Admin)
> - the alternative would be setting the version at time of publication \_but\_ we run into potential problems there with content being unpublished and republished for any reason (send as email, force automations to run, etc)
> \- \[x\] Remove card-markdown card alias in \`kg-default-cards\`
> \- \[x\] Remove handling of \`cardOptions.version\` that is no longer used
> \- \[x\] Update mobiledoc renderers to use top-level \`ghostVersion\`
> \- \[x\] Update header id generation to use a less destructive algorithm (closes https://github.com/TryGhost/Ghost/issues/9740)
> - \[x\] \[Top-level DOM modifier\](https://github.com/TryGhost/Koenig/blob/master/packages/kg-mobiledoc-html-renderer/lib/mobiledoc-html-renderer.js#L34-L55)
> - \[x\] \[Markdown renderer\](https://github.com/TryGhost/Koenig/blob/master/packages/kg-markdown-html-renderer/lib/markdown-html-renderer.js#L11-L20)

Tocbot does not work with special characters which are in other languages (e.g. Polish: ą, ć, ę, ł, ń, ó, ś, ź, ż). It is since Ghost 4.0.

## Issue example

Here is the `id` generated by Ghost:

```xml
<h2 id="2-z-kim-mo%C5%BCesz-kontaktowa%C4%87-si%C4%99-w-sprawie-przetwarzania-twoich-danych-osobowych">

```

Here is the `id` taken by Tocbot:

```xml
<a href="#2-z-kim-mo%C5%BCesz-kontaktowa%C4%87-si%C4%99-w-sprawie-przetwarzania-twoich-danych-osobowych" class="toc-link node-name--H2 ">

```

The browser (Firefox/Chrome) opens the link under:

```xml
${url}/#2-z-kim-możesz-kontaktować-się-w-sprawie-przetwarzania-twoich-danych-osobowych

```

and has issues with navigating to correct `<h2>` tag.

## Fix

I’ve resolved the issue by taking the following script:

> <https://github.com/tscanlin/tocbot/blob/master/src/utils/make-ids.js>

and making some customization for my language special characters:

```js
<script>
function makeIds() {
    var content = document.querySelector('.gh-content');
    var headings = content.querySelectorAll('h2, h3');
    var headingMap = {};

    Array.prototype.forEach.call(headings, function (heading) {
        var id = heading.textContent.trim().toLowerCase()
            .split(' ').join('-').replace(/[!@#$%^&*():?\[\]'+,;=<>{}|\\`]/ig, '').replace(/ą/ig, 'a').replace(/ć/ig, 'c')
            .replace(/ę/ig, 'e').replace(/ł/ig, 'l').replace(/ń/ig, 'n').replace(/ó/ig, 'o').replace(/ś/ig, 's')
            .replace(/[źż]/ig, 'z').replace(/\//ig, '-');
        heading.id = id;
    });
}
makeIds();
</script>

```

I’ve pasted it at the end of `page.hbs` and `post.hbs` (because I use ToC there).

## Fix example

Here is the `id` generated by the above script:

```xml
<h2 id="2.-z-kim-mozesz-kontaktowac-sie-w-sprawie-przetwarzania-twoich-danych-osobowych" tabindex="-1">

```

Here is the `id` taken by Tocbot:

```xml
<a href="#2.-z-kim-mozesz-kontaktowac-sie-w-sprawie-przetwarzania-twoich-danych-osobowych" class="toc-link node-name--H2 ">

```

The browser (Firefox/Chrome) opens the link under:

```xml
${url}/#2.-z-kim-mozesz-kontaktowac-sie-w-sprawie-przetwarzania-twoich-danych-osobowych

```

---

<div class="post-metadata">

**Author:** ![JustinCEO](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/justinceo/32/13232_2.png) [@JustinCEO](https://forum.ghost.org/u/JustinCEO)\
**Post date:** [May 11, 2021, 5:14am UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/15 "2021-05-11T05:14:58Z")

</div>

would there be a relatively easy way to only have a ToC show up on pages that have a particular tag? (My use case: I’m wanting to use Ulysses integration to write my posts and it’d be quite convenient to just slap on a “toc” tag in Ulysses whenever i want a ToC and call it a day)

I don’t expect a fully explanation btw - willing to do some work. But just some pointers on where to get started and links to anything roughly similar that’s been done would be great 🙂

---

<div class="post-metadata">

**Author:** ![Stromfeldt](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/stromfeldt/32/13572_2.png) [@Stromfeldt](https://forum.ghost.org/u/Stromfeldt)\
**Post date:** [May 11, 2021, 5:20am UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/16 "2021-05-11T05:20:17Z")

</div>

@JustinCEO See this comment from earlier today:

> [@Really quite nice for a personal/professional blog](https://forum.ghost.org/t/really-quite-nice-for-a-personal-professional-blog/22460/5):
>
> @lorcand I suppose there might be some kind of JS way to detect if there are any H1s or H2 etc. within a page’s .c-content area and which you could easily just drop into your site’s code injection footer, but I don’t know JS so I can’t help you there. Alternatively, the way I remove the TOC section on my site when I don’t want it there is to integrate a {{#has}} helper. Depending on if you have fewer posts that utilise TOC functionality or not, you can create either the internal tag #yes-TOC or…

---

<div class="post-metadata">

**Author:** ![JustinCEO](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/justinceo/32/13232_2.png) [@JustinCEO](https://forum.ghost.org/u/JustinCEO)\
**Post date:** [May 11, 2021, 4:23pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/17 "2021-05-11T16:23:56Z")

</div>

I set up a development version of Ghost on my local machine.

So if I just include

```
<aside class="toc"></aside>

```

in my post.hbs file, Ghost displays the ToC on all posts

However, if I try to make the TOC display conditional on a tag being present, e.g. with:

```auto
{{#has tag="#TOC"}}
    <aside class="toc"></aside>
{{/has}}

```

then nothing happens on either tagged or untagged posts

---

<div class="post-metadata">

**Author:** ![JustinCEO](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/justinceo/32/13232_2.png) [@JustinCEO](https://forum.ghost.org/u/JustinCEO)\
**Post date:** [May 11, 2021, 4:28pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/18 "2021-05-11T16:28:28Z")

</div>

Ghost doesn’t seem to care where I put the `aside` HTML snippet if I’m using the “floating” fixed position ToC, per what @denvergeeks said in his earlier post. Does Ghost care where I put a `has`? Just trying to speculate on what the trouble might be

I’ve double checked that I actually tagged the post I’m testing with a TOC tag, that it’s a blog post, and that it’s fully updated, and I tried restarting Ghost.

---

<div class="post-metadata">

**Author:** ![JustinCEO](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/justinceo/32/13232_2.png) [@JustinCEO](https://forum.ghost.org/u/JustinCEO)\
**Post date:** [May 11, 2021, 4:55pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/19 "2021-05-11T16:55:10Z")

</div>

lol i had a # symbol before my tag, that was wrecking the whole thing.

the correct code:

```auto
{{#has tag="TOC"}}
    <aside class="toc"></aside>
{{/has}}

```

it works 🙌

---

<div class="post-metadata">

**Author:** ![denvergeeks](https://sea1.discourse-cdn.com/flex015/user_avatar/forum.ghost.org/denvergeeks/32/7401_2.png) [@denvergeeks](https://forum.ghost.org/u/denvergeeks)\
**Post date:** [May 11, 2021, 5:08pm UTC](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584/20 "2021-05-11T17:08:54Z")

</div>

Nice, @JustinCEO !

[Next page](https://forum.ghost.org/t/table-of-contents-tutorial-for-casper-version-4-simplified/22584.md?page=2)
