Socket
Book a DemoInstallSign in
Socket

astro-toc-generator

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

astro-toc-generator

Table of Contents generator for Astro.js with Sanity integration

1.1.2
latest
Source
npmnpm
Version published
Maintainers
1
Created
Source

Alt Text

⚡Astro TOC Generator for Sanity

npm version npm downloads TypeScript Built with Astro

A table of contents generator for Astro.js that works specifically with Sanity CMS blog content. This component automatically generates a table of contents from your Sanity portable text content, with support for custom styling and smooth scrolling.

💡 Features

  • 🎯 Specifically designed for Sanity CMS content
  • 🎨 Fully customizable styling with CSS variables
  • 🔄 Active section highlighting with parent-child relationships
  • 🔗 Smooth scrolling support
  • 📚 Support for all heading levels (h1-h6)
  • 🌳 Hierarchical structure support
  • 🎨 Different styling per heading level
  • 🎯 Accurate scroll position tracking

📥 Installation

npm install astro-toc-generator

💻 Usage

  • Import the component and styles in your Astro page:
---
import { TableOfContents, generateSlug } from 'astro-toc-generator';
import 'astro-toc-generator/styles'; // Import base styles

// Your Sanity portable text content
const content = [
  {
    _type: 'block',
    style: 'h1',
    children: [{ _type: 'span', text: 'Welcome to My Blog' }]
  },
  // ... more content blocks
];
---

<div class="layout">
  <aside>
    <TableOfContents
      content={body?.value}
      maxLevel={3}
      containerClass="toc-container"
      smoothScroll={true}
      activeClass="active"
      linkClass="toc-link"
      listClass="toc-list"
      listItemClass="toc-item"
      headingSelector="h1, h2, h3"
    />
  </aside>
  <article>
    <!-- Important: Add matching IDs to your headings using generateSlug -->
    <h1 id={generateSlug('Welcome to My Blog')}>Welcome to My Blog</h1>
    <h2 id={generateSlug('Introduction')}>Introduction</h2>
    <!-- ... more content -->
  </article>
</div>
  • Add required CSS and customize the styling:
:root {
  /* Basic setup */
  scroll-behavior: smooth;

  /* Customize TOC appearance */
  --toc-bg: #f8f9fa;
  --toc-text-color: #666;
  --toc-border-color: #eaeaea;
  --toc-active-color: #0d6efd;
  --toc-active-bg: rgba(13, 110, 253, 0.05);
  --toc-hover-color: #000;
  --toc-hover-bg: rgba(0, 0, 0, 0.05);
  --toc-indent-size: 1rem;
  --toc-border-radius: 8px;
  --toc-transition: all 0.2s ease;
}

/* Layout setup */
.layout {
  display: grid;
  grid-template-columns: 3fr 1fr;
  gap: 2rem;
}

aside {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
  padding-top: 2rem;
}

/* Add scroll margin to headings */
h1,
h2,
h3,
h4,
h5,
h6 {
  scroll-margin-top: 2rem;
  padding-top: 2rem;
}

/* Optional: Add box shadow to TOC */
.toc-container {
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* Optional: Override specific styles */
.toc-link.active {
  color: red; /* Change active color */
}

📌 Important Notes

  • Heading IDs: Add IDs to your headings using the generateSlug function
  • CSS Variables: Customize appearance using CSS variables in :root
  • Scroll Behavior: Add scroll-behavior: smooth to your root element
  • Scroll Margins: Add scroll-margin-top to headings for proper positioning

📝 Supported Props

PropTypeDefaultDescription
contentPortableTextBlock[] or any[]requiredYour Sanity portable text content
containerClassstring'toc-container'Class for the container element
listClassstring'toc-list'Class for the list element
listItemClassstring'toc-item'Class for list items
linkClassstring'toc-link'Class for links
activeClassstring'active'Class for active links
smoothScrollbooleantrueEnable/disable smooth scrolling
maxLevelnumber6Maximum heading level to include (1-6)
headingSelectorstring'h1, h2, h3, h4, h5, h6'Selector for headings to track

🚀 Heading Level Mapping

The component automatically maps Sanity heading styles to their corresponding HTML levels:

Sanity StyleHTML LevelDescription
h1Level 1Main title/chapter heading
h2Level 2Section heading
h3Level 3Subsection heading
h4Level 4Sub-subsection heading
h5Level 5Minor heading
h6Level 6Smallest heading

Level-based CSS Classes

Each TOC item receives classes based on its heading level for targeted styling:

/* Target specific heading levels */
.toc-item.level-1 {
  /* h1 headings */
}
.toc-item.level-2 {
  /* h2 headings */
}
.toc-item.level-3 {
  /* h3 headings */
}
.toc-item.level-4 {
  /* h4 headings */
}
.toc-item.level-5 {
  /* h5 headings */
}
.toc-item.level-6 {
  /* h6 headings */
}

/* Example: Style different levels differently */
.toc-item.level-1 .toc-link {
  font-weight: bold;
  font-size: 1.1em;
}

.toc-item.level-2 .toc-link {
  font-weight: 600;
}

.toc-item.level-3 .toc-link {
  font-weight: normal;
  opacity: 0.8;
}

Depth-based Classes

The component also provides depth classes for nested items:

/* Target by nesting depth */
.toc-item.depth-0 {
  /* Root level items */
}
.toc-item.depth-1 {
  /* First level nested items */
}
.toc-item.depth-2 {
  /* Second level nested items */
}

/* Example: Increase indentation per depth level */
.toc-item.depth-1 {
  padding-left: calc(var(--toc-indent-size) * 1);
}

.toc-item.depth-2 {
  padding-left: calc(var(--toc-indent-size) * 2);
}

🪄 CSS Variables

VariableDefaultDescription
--toc-bg#f8f9faBackground color of the TOC
--toc-text-color#666Default text color
--toc-border-color#eaeaeaBorder color
--toc-active-color#0d6efdColor for active items
--toc-active-bgrgba(13, 110, 253, 0.05)Background for active items
--toc-hover-color#000Text color on hover
--toc-hover-bgrgba(0, 0, 0, 0.05)Background on hover
--toc-indent-size1remIndentation size for nested items
--toc-border-radius8pxBorder radius of the container
--toc-transitionall 0.2s easeTransition for hover/active states

🛠️ Utility Functions

import { generateSlug } from "astro-toc-generator";

// Generate URL-friendly slugs for heading IDs
const slug = generateSlug("Your Heading Text");

✏️ Customization Examples

  • Style different heading levels:
/* Main headings (h1) - larger and bold */
.toc-item.level-1 .toc-link {
  font-size: 1.2em;
  font-weight: bold;
  color: #000;
}

/* Subheadings (h2) - medium weight */
.toc-item.level-2 .toc-link {
  font-size: 1.1em;
  font-weight: 600;
  color: #333;
}

/* Minor headings (h3+) - lighter */
.toc-item.level-3 .toc-link,
.toc-item.level-4 .toc-link,
.toc-item.level-5 .toc-link,
.toc-item.level-6 .toc-link {
  font-size: 1em;
  font-weight: normal;
  color: #666;
}
  • Progressive indentation by level:
.toc-item.level-2 {
  padding-left: 1rem;
}
.toc-item.level-3 {
  padding-left: 2rem;
}
.toc-item.level-4 {
  padding-left: 3rem;
}
.toc-item.level-5 {
  padding-left: 4rem;
}
.toc-item.level-6 {
  padding-left: 5rem;
}
  • Change active state colors:
:root {
  --toc-active-color: red;
  --toc-active-bg: rgba(255, 0, 0, 0.05);
}
  • Modify indentation:
:root {
  --toc-indent-size: 1.5rem;
}
  • Change container appearance:
:root {
  --toc-bg: #fff;
  --toc-border-radius: 12px;
}

.toc-container {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
  • Custom hover effects:
:root {
  --toc-hover-color: #0d6efd;
  --toc-hover-bg: rgba(13, 110, 253, 0.1);
}

📚 Example Content Structure

Here's how your Sanity content structure should look:

const content = [
  // Level 1 - h1
  {
    _type: "block",
    style: "h1",
    children: [{ _type: "span", text: "Main Title" }],
  },
  // Level 2 - h2
  {
    _type: "block",
    style: "h2",
    children: [{ _type: "span", text: "Section Title" }],
  },
  // Level 3 - h3
  {
    _type: "block",
    style: "h3",
    children: [{ _type: "span", text: "Subsection Title" }],
  },
];

📦 Quick Start & Development

npm create astro@latest -- --template minimal

Open in StackBlitz Open with CodeSandbox Open in GitHub Codespaces

💼 Explore my personal work and projects:

Visit my portfolio at Bhargav Patel to explore my work, projects, and what I’ve been building lately.

🪪 License

MIT

Keywords

astro

FAQs

Package last updated on 10 Jun 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.