How to Add a Table of Contents to Shopify Blog Posts

How to Add a Table of Contents to Shopify Blog Posts
Yes, you can add a table of contents to a Shopify blog post, and you don't need a theme developer to do it. The fastest way is a small Liquid snippet that reads your post's headings and builds a clickable list automatically, no manual link-fixing every time you publish. Grab that below, or skip to the no-code app option if you'd rather not touch theme files at all.
Here are the three ways to do it, fastest first.
Method 1: Liquid snippet, auto-generated from headings
This is the version worth bookmarking. It scans your article's H2 and H3 tags and builds the table of contents for you, so you never go back and manually update jump links every time you edit a post.
A note before you copy this in: this snippet is written to Shopify's standard theme architecture (Online Store 2.0, section-based article templates) and follows documented Liquid syntax. Drop it into a duplicate theme first and check it against your actual article template before publishing it anywhere.
Step 1: create the snippet file
In your theme editor, go to Snippets and add a new file called table-of-contents.liquid. Paste this in:
{% assign toc_headings = article.content | split: '</h2>' %}
<div class="toc-wrapper" id="toc-wrapper">
<p class="toc-title">In this article</p>
<ul class="toc-list">
{% for heading in toc_headings offset: 0 %}
{% assign heading_text = heading | split: '>' | last | strip_html | strip %}
{% if heading_text != blank %}
{% assign heading_slug = heading_text | handleize %}
<li><a href="#{{ heading_slug }}">{{ heading_text }}</a></li>
{% endif %}
{% endfor %}
</ul>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
var article = document.querySelector('.article-content, .rte');
if (!article) return;
var headings = article.querySelectorAll('h2, h3');
headings.forEach(function (heading) {
var slug = heading.textContent
.toLowerCase()
.trim()
.replace(/[^a-z0-9\s-]/g, '')
.replace(/\s+/g, '-');
heading.id = slug;
});
});
</script>
Step 2: render it inside your article template
Open main-article.liquid (or your article section file) and add this line right after the article title, before the body content renders:
{% render 'table-of-contents' %}
Step 3: style it
Add basic styling in your theme's CSS file so it doesn't look like a raw list:
.toc-wrapper {
background: #f7f7f7;
border-radius: 8px;
padding: 16px 20px;
margin: 24px 0;
}
.toc-title {
font-weight: 600;
margin-bottom: 8px;
}
.toc-list {
list-style: none;
padding-left: 0;
}
.toc-list li {
margin-bottom: 6px;
}
What this does: the Liquid loop pulls every H2 in your article body and turns it into a link. The JavaScript block matches those links to real heading IDs on the live page, so clicking a TOC item jumps straight to that section. Once it's in your template, every future post gets a TOC automatically. You never touch this file again.
Method 2: manual anchor links
If you'd rather not touch template files, you can build a TOC by hand for a single post.
- Add an ID to each heading directly in the HTML editor, like
<h2 id="method-2">Method 2</h2>. - At the top of the post, add a list linking to each ID:
<a href="#method-2">Manual anchor links</a>. - Publish and test each link.
This works fine for a one-off post, but it breaks the moment you edit a heading and forget to update the matching link. The anchor text in your TOC list matters too. A link that just says "click here" tells a reader and a search engine nothing, but a link that says "jump to sticky scroll setup" tells both exactly what's waiting on the other end. That's the same logic behind writing descriptive anchor text everywhere else on your blog, not just in a TOC.
Method 3: StoreBlog
StoreBlog builds the TOC in, so you skip the code entirely. Its blog editor includes a table of contents toggle alongside SEO scoring and internal link suggestions, so the TOC gets generated as part of writing and formatting the post rather than as a separate step. Try StoreBlog if you want the TOC handled without editing theme files.
Install StoreBlog from the Shopify App Store now.
Making it sticky on scroll
A TOC that sits at the top of a long post is easy to lose once someone scrolls past it. To keep it visible, wrap the JavaScript above with a scroll listener that adds a .sticky class once the reader passes the TOC's original position:
window.addEventListener('scroll', function () {
var toc = document.getElementById('toc-wrapper');
if (!toc) return;
var offset = toc.offsetTop;
if (window.scrollY > offset) {
toc.classList.add('sticky');
} else {
toc.classList.remove('sticky');
}
});
Then give .sticky a position: fixed rule in your CSS with a sensible top offset. Test this on mobile especially, since a sticky element on a small screen can eat up more space than it's worth.
Does a table of contents help SEO?
A TOC does not directly move your rankings. What it does is make your content easier to crawl and easier to read, which are two things Google does reward indirectly.
Jump links can appear as sitelinks under your result in Google search, which improves click-through rate. A clear heading structure also helps dwell time, since readers who find what they need faster tend to stay on the page longer instead of bouncing back to search. Neither of those is a ranking factor by itself, but both feed into signals Google does track.
What a TOC will not do is fix a post that's thin or poorly researched. Treat it as a readability and UX improvement that happens to carry some SEO upside, not a shortcut around writing a genuinely useful article. For more on the fundamentals a TOC sits on top of, see the full Shopify blog SEO checklist.
FAQ
Does Shopify have a built-in table of contents feature?
No. Shopify's native blog editor has no built-in TOC option. You need either the Liquid snippet above, a manual anchor link setup, or an app.
Will a table of contents slow down my blog post?
Not meaningfully. The snippet above adds a small amount of Liquid and a few lines of JavaScript, both of which are lightweight compared to most theme apps.
Can I use a table of contents on product pages too, not just blog posts?
Yes, the same Liquid and JavaScript pattern works on any page template with H2 or H3 headings, you'd just render the snippet inside that template instead of the article template.


