Skip to content

Free Tool

Table of Contents Generator

Auto-generate a clickable table of contents from your page headings. Choose sidebar, inline, or floating style with smooth scroll navigation.

Why this matters

A table of contents helps readers scan long pages and jump to relevant sections. It improves time-on-page metrics, helps with SEO (Google can show jump links in search results), and makes documentation or guide-style content far more usable.

Customize

Behavior

Colors

Live Preview

Generated Code

<style>
  html { scroll-behavior: smooth; }
  .sqs-toc-nav {
    background: #f9f9f9;
    border: 1px solid #e0e0e0;
    padding: 20px 24px;
    margin: 24px 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  }
  .sqs-toc-title {
    font-size: 14px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: #333333;
    margin-bottom: 12px;
  }
  .sqs-toc-toggle {
    display: none;
    background: none;
    border: none;
    font-size: 13px;
    color: #333333;
    cursor: pointer;
    padding: 0;
    margin-left: 8px;
  }
  .sqs-toc-list {
    list-style: decimal;
    padding-left: 20px;
    margin: 0;
  }
  .sqs-toc-list .toc-h3 {
    padding-left: 16px;
  }
  .sqs-toc-list .toc-h4 {
    padding-left: 32px;
  }
  .sqs-toc-link {
    display: block;
    padding: 4px 0;
    font-size: 14px;
    color: #333333;
    text-decoration: none;
    transition: color 0.2s;
  }
  .sqs-toc-link:hover {
    color: #000000;
  }
  .sqs-toc-link.active {
    color: #000000;
    font-weight: 600;
  }
  @media (max-width: 768px) {
    .sqs-toc-nav {
      max-width: 100% !important;
      position: static !important;
      bottom: auto !important;
      right: auto !important;
      box-shadow: none !important;
    }
    .sqs-toc-list {
      display: none;
    }
    .sqs-toc-nav.expanded .sqs-toc-list {
      display: block;
    }
    .sqs-toc-toggle {
      display: block !important;
    }
  }
</style>

<script>
(function() {
  var headings = document.querySelectorAll('h2, h3');
  if (headings.length < 2) return;

  // Build TOC
  var nav = document.createElement('nav');
  nav.className = 'sqs-toc-nav';

  var titleRow = document.createElement('div');
  titleRow.style.cssText = 'display:flex;align-items:center;justify-content:space-between;';
  var title = document.createElement('div');
  title.className = 'sqs-toc-title';
  title.textContent = 'Table of Contents';
  titleRow.appendChild(title);
  var toggleBtn = document.createElement('button');
  toggleBtn.className = 'sqs-toc-toggle';
  toggleBtn.textContent = '\u25BC';
  titleRow.appendChild(toggleBtn);
  nav.appendChild(titleRow);

  var list = document.createElement('ol');
  list.className = 'sqs-toc-list';

  headings.forEach(function(heading, i) {
    // Generate ID if none exists
    if (!heading.id) {
      heading.id = 'section-' + i + '-' + heading.textContent.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
    }
    var li = document.createElement('li');
    li.className = 'toc-' + heading.tagName.toLowerCase();
    var a = document.createElement('a');
    a.className = 'sqs-toc-link';
    a.href = '#' + heading.id;
    a.textContent = heading.textContent;
    li.appendChild(a);
    list.appendChild(li);
  });

  nav.appendChild(list);

  var firstHeading = document.querySelector('h2');
  if (firstHeading) firstHeading.parentNode.insertBefore(nav, firstHeading);

  // Highlight current section
  var tocLinks = document.querySelectorAll('.sqs-toc-link');
  var headingEls = [];
  tocLinks.forEach(function(link) {
    var target = document.getElementById(link.getAttribute('href').substring(1));
    if (target) headingEls.push({ el: target, link: link });
  });

  function updateActive() {
    var scrollPos = window.scrollY + 120;
    var current = null;
    headingEls.forEach(function(h) {
      if (h.el.offsetTop <= scrollPos) current = h;
    });
    tocLinks.forEach(function(l) { l.classList.remove('active'); });
    if (current) current.link.classList.add('active');
  }
  window.addEventListener('scroll', updateActive, { passive: true });
  updateActive();
  // Mobile toggle
  var toggle = nav.querySelector('.sqs-toc-toggle');
  if (toggle) {
    toggle.addEventListener('click', function() {
      nav.classList.toggle('expanded');
    });
  }
})();
</script>

How to add this to Squarespace

  1. Go to Settings → Advanced → Code Injection
  2. Paste the generated code into the Footer section.
  3. Make sure your blog posts or pages use proper heading hierarchy (H2, H3, H4).
  4. The TOC auto-generates from your headings. It only appears when there are 2 or more headings on the page.

A little over your head?

No shame — this stuff is hard. Let the pros handle it.

Long Drive MarketingTalk to Long Drive Marketing →