Skip to content

Table of Contents

The headings of the current page, as a rail beside it or a folded list above it.

View source View as Markdown

The table of contents lists the second and third level headings of a page. From 1200px it is a rail right of the content that marks the heading the reader has scrolled to. Below that, it folds into a list at the top of the page.

TableOfContentsDemo.vue
<template>
  <docs-toc-list :links="links" active-id="usage" class="w-56" />
</template>

<script setup lang="ts">
import type { TocLink } from '@nuxt/content'

const links: Array<TocLink> = [
  { id: 'anatomy', depth: 2, text: 'Anatomy' },
  { id: 'usage', depth: 2, text: 'Usage' },
  {
    id: 'api-reference',
    depth: 2,
    text: 'API reference',
    children: [
      { id: 'docstoc', depth: 3, text: 'DocsToc' },
      { id: 'docstocinline', depth: 3, text: 'DocsTocInline' },
      { id: 'docstoclist', depth: 3, text: 'DocsTocList' },
    ],
  },
]
</script>

Anatomy

The layer renders both versions on every page. Each shows its own width and hides at the other.

NameRequiredDescription
DocsTocThe rail. Follows the scroll position and keeps the marked heading in view.
DocsTocList true The headings, nested by level.
DocsTocFooterRenders nothing until you replace it.
DocsTocInlineThe folded list above the content.
DocsTocList true The same headings, without a marked one.

Usage

Both versions take the links Nuxt Content writes into a page’s body.

<template>
  <docs-toc :links="page?.body?.toc?.links ?? []" />
</template>

The layer lists headings down to the third level. To change that, set content.build.markdown.toc.depth in nuxt.config.ts.

DocsTocList renders the links without the rail, so it works anywhere a page needs its headings. The heading named by active-id is marked with aria-current.

<template>
  <docs-toc-list :links="links" active-id="usage" />
</template>

Under the rail

DocsTocFooter sits under the rail and renders nothing. Replace it with a component of the same name in your app to fill the space, for a list of sponsors for example.

app/components/DocsTocFooter.vue
<template>
  <p class="docs-caption text-surface-muted mt-10 px-2">
    Sponsored by Magic as a Service™
  </p>
</template>

API reference

DocsToc

PropTypeDefault
links
Array<TocLink>none

DocsTocInline

PropTypeDefault
links
Array<TocLink>none

DocsTocList

PropTypeDefault
links
Array<TocLink>none
activeId
stringnone

DocsTocFooter

Takes no props.