Ghost TOC - Automatic Table of Contents for Your Posts

Hi everyone! :waving_hand:

I’ve been working on a lightweight solution for adding automatic table of contents to Ghost posts, and I’d love to share it with the community. It’s completely free and open source (MIT License).

What is Ghost TOC?

Ghost TOC is a simple JavaScript script that automatically generates a table of contents from your article headings. Just add a <toc> tag where you want the TOC to appear, and it builds itself from your H2-H6 headings.

Example of Ghost TOC in action on a blog post:

Why I Built This

Ghost doesn’t have built-in TOC functionality, and existing solutions either required external dependencies, only worked in sidebars, or needed server file modifications. I wanted something that lives inside the post content itself:

  • :white_check_mark: No external dependencies
  • :white_check_mark: Places TOC directly in your post content (not a sidebar widget)
  • :white_check_mark: Install once via Code Injection, use everywhere
  • :white_check_mark: Just add <toc> tag wherever you want it in your article

Key Features

  • :page_facing_up: Lives inside your post content (place it anywhere in your article)
  • :rocket: Automatic generation from H2-H6 headings
  • :mobile_phone: Collapsible with show/hide toggle
  • :artist_palette: Customizable colors and styling
  • :globe_showing_europe_africa: Multi-language support (customize the title)
  • :floppy_disk: Database efficient - no script duplication per post
  • :package: Lightweight (~2KB minified)

Quick Example

In your Ghost post editor, add an HTML block and insert:

<!-- Simple TOC -->
<toc title="Table of Contents"></toc>

<!-- Collapsible with custom colors -->
<toc
  title="What You'll Learn"
  collapsible="true"
  show-text="Show Contents"
  hide-text="Hide Contents"
  border-color="#3498db"
  bg-color="#ecf0f1">
</toc>

The TOC appears right where you place the tag - typically after your intro paragraph, before the main content.

Installation

  1. Copy the script from dist/ghost-toc.min.js (click “Copy raw file” button)
  2. Go to Ghost Admin → Settings → Code Injection
  3. Paste into Site Footer
  4. Save and you’re done!

Now just add <toc> tags to your posts and save them as snippets for quick reuse.

Note: This project evolved from my original blog post, but the GitHub repository now has complete installation instructions, examples, and documentation - everything you need is there!

Repository

The project is now on GitHub with full documentation and examples:

:link: GitHub - vlavrynovych/ghost-toc: Lightweight Table of Contents generator for Ghost blog platform. Zero dependencies, collapsible functionality, works via code injection. Just add <toc> tag to your posts!

The repository includes:

  • Complete installation guide
  • Working examples (basic, collapsible, full customization)
  • Build system and GitHub Actions automation
  • Comprehensive documentation

Try It Out

Check out the examples to see it in action, or view it live on my blog.

Would love to hear your feedback or ideas for improvements!

Happy blogging!

5 Likes

Nice job! Thanks for sharing it.

Only missing part of this approach, it doesn’t work on e-mails and Social Web reader, since they don’t run JavaScript. But still, it’s good for the people who don’t mind that.

2 Likes

Hi, thanks for the feedback. For email, I believe the only viable option is a static TOC, which has to be written manually.

My implementation can partially help here: you can generate the TOC, open the preview, copy the generated TOC, and then replace it with the copied version to make it static. This should save some time, although any changes to the headers afterward would require repeating the same steps. Overall, it’s a reasonable option to use before publishing.

1 Like

Here’s a static TOC generator I shared a while back!

2 Likes

Yep, something like this will work as well — you just need to remember to provide a preview link if the post isn’t published yet.

I’ll admit, I’m a bit lazy :grinning_face_with_smiling_eyes: I wanted a quick solution for myself, so I created a TOC snippet and reuse it for every post. Ideally, I should update the theme’s post template to fix the TOC in a consistent position across all posts. However, since I occasionally write in two languages, that approach isn’t ideal for me. I’d likely need an additional script to detect the post’s language and apply the correct TOC title.

2 Likes

Ghost TOC Updates: v2.2.0 & v2.3.0

Hey everyone! :waving_hand: Two updates with improvements and new features I needed for my own blog.

v2.2.0 - Quality Improvements

Better screen reader support, bug fixes, and improved error messages.

v2.3.0 - New Optional Features

Your existing TOC tags work exactly as before. These are optional features you can add if you want:

:bullseye: Filter headings

Show only certain heading levels:

<toc levels="2,3"></toc>  <!-- Only H2 and H3 -->

:floppy_disk: Remember reader’s preference

TOC stays collapsed/expanded as the reader left it:

<toc collapsible="true" remember-state="true"></toc>

:pushpin: Start collapsed

Great for long articles:

<toc collapsible="true" default-state="collapsed"></toc>

:memo: Numbered lists

<toc list-style="numbers"></toc>  <!-- 1, 2, 3 instead of bullets -->
<toc list-style="none"></toc>     <!-- No markers -->

:prohibited: Skip sections

Exclude specific headings by their ID:

<toc exclude="about-author,related-posts"></toc>

:artist_palette: Custom styling

Add your own CSS classes:

<toc class="my-custom-style"></toc>

Combined example

<toc
  title="In This Article"
  collapsible="true"
  default-state="collapsed"
  remember-state="true"
  levels="2,3"
  list-style="numbers">
</toc>

How to update

Replace the script in Settings → Code Injection → Site Footer

:inbox_tray: Download v2.3.0

More info


Happy blogging! :books:

1 Like