nuxt-toc is a Nuxt 3 and 4 module to display a table of contents (TOC) when using content created with the @nuxt/content module. Since v.3.0.0, nuxt-toc supports both versions of @nuxt/content, v2 and v3. nuxt-toc is also compatible with Nuxt 3 and 4.
Note
For more information, check out the full documentation.
Languages: 🇺🇸 English · 🇹🇼 中文 · 🇩🇪 Deutsch · 🇪🇸 Español · 🇫🇷 Français · 🇸🇦 فارسی
- Content v2 (
queryContent) and v3 (queryCollection) - Pass-in
:toc(recommended) or optional auto-fetch - Nested link depth control
- Active section highlighting (scroll-spy)
- Optional smooth scroll + sticky-header offset
- Stable CSS class/id hooks for theming
- Accessible list markup
# Adding to existing site
npx nuxi module add nuxt-toc
# Or install manually
npm install nuxt-tocIf you installed nuxt-toc via nuxi module, you can skip this step.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-toc', '@nuxt/content'],
})Prefer passing the TOC from your page query. Make sure to use the correct version to match your @nuxt/content version.
<!-- MyPage.vue -->
<script setup lang="ts">
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () =>
queryCollection('content').path(route.path).first(),
)
</script>
<template>
<ContentRenderer v-if="page" :value="page" />
<TableOfContents :toc="page?.body?.toc" />
</template><!-- MyPage.vue -->
<script setup lang="ts">
const route = useRoute()
constage { data } = queryContent(route.path).findOne()
</script>
<template>
<ContentRenderer v-if="page" :value="page" />
<TableOfContents :toc="page?.body?.toc" />
</template>Or auto-fetch by path:
<TableOfContents path="/docs/intro" />| Prop | Type | Default | Description |
|---|---|---|---|
toc |
Toc | null |
null |
Prefetched TOC (page.body.toc). Skips fetch when set. |
path |
string |
'' |
Auto-fetch path (default: current route). |
collection |
string |
'' |
Content v3 collection (default: nuxtToc.collection / content). |
depth |
number |
2 |
Max nesting depth of the link tree (1 = top-level only). |
isSublistShown |
boolean |
true |
When false, forces depth 1. |
isTitleShownWithNoContent |
boolean |
false |
Keep showing the title when there are no links. |
title |
string |
'Table of Contents' |
Heading text. |
scrollSpy |
boolean |
true |
Active-section highlighting. |
rootMargin |
string |
'0px 0px -80% 0px' |
IntersectionObserver rootMargin. |
smooth |
boolean |
false |
Smooth scroll on link click. |
scrollOffset |
number |
0 |
Scroll offset in px (sticky header). |
Customize nuxt-toc via the following settings (values used here are default values).
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
'nuxt-toc',
... // Your other modules
],
nuxtToc: {
collection: 'content',
depth: 2,
scrollSpy: true,
rootMargin: '0px 0px -80% 0px',
smooth: false,
scrollOffset: 0,
},
})To learn more about nuxt-toc and how to use or style it, check out the full documentation. You will find guides, recipes, and more.
hanyujie2002 (yujiehan2002@outlook.com)
thaikolja (kolja.nolte@gmail.com)
This project is licensed under the MIT License.