## Auto Generate TOC

I largely followed the excellent instructions here

Styling TOC: see commit

Note: there is a recent fix in the theme regarding scroll-margin-top

.post-full-content h1,
.post-full-content h2,
.post-full-content h3,
.post-full-content h4,
.post-full-content h5,
.post-full-content h6 {
color: color-mod(var(--darkgrey) l(-5%));
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
scroll-margin-top: 110px;
}

It makes the TOC scrolling a bit weird and is redundant with, we can keep either one of them.

.post-content h2::before,
.post-content h3::before {
display: block;
content: " ";
height: 84px;
margin-top: -84px;
visibility: hidden;
}

## Make it Conditional 🎉

Now, there are a few problems. Because the styling is applied on all .post-full-content there are two issues

1. Post without TOC will still have its main text area off-centered to make room for the TOC that doesn't exist
2. Pages will not have POC (because we only adjusted post.hbs, but it will also make its content off-centered for TOC area on the right

The main thing making this extra column appear is

.post-full-content {
display: grid;
grid-template-columns: 1fr 0.2fr;
margin: 0;
}

We can give it a more special name .post-full-content-with-toc.

Then we only add this class to post pages which actually have a non empty TOC. One way to achieve this is to add the following Javascript somewhere, for example in post.hbs's script block (see commit here).

var hasTOC = $(".toc").children().length if (hasTOC) {$(".post-full-content").addClass("post-full-content-with-toc");
}


## Optional Configurations

Optionally, you can also disable TOC when there aren't say more than 5 entries in the TOC list.

var hasTOC = $(".toc").children().length; if (hasTOC) { var n =$(".toc li").length;
if (n < 5) {
$(".toc").remove(); } else {$(".post-full-content").addClass("post-full-content-with-toc");
}
}


One small thing related to membership, when a reader does not have access to a post, there will be a call to action (CTA) but no content, in this case it doesn't make sense to have a TOC either. To adjust for this, wrap the previous <aside> section with {{#if access}} to check whether the user has access to the post.

{{#if access}}
<aside class="toc-container">
<div class="toc"></div>
</aside>
{{/if}}

See here for more Ghost editing tips: 👇