# Table of contents

> A marker for a contents list, ahead of the renderers that build one.

Source: https://docxcelerate.com/docs/nodes/table-of-contents/

The kind is part of the document schema and both renderers accept it. What is missing is downstream rather than in the authoring: the element places the marker and carries its title, and building the entries from the surrounding section titles is a renderer's job.

> **What the renderers do today:** Both shipped renderers print the title and nothing else. Building the entries from the surrounding section titles is the intent, not yet implemented.

- **Helpers:** `TableOfContents`
- **Node kind:** `tableOfContents`
- **Category:** Structure
- **Resolves:** By the renderer
- **Children:** None. The entries would come from the sections beside it.

| Option | Type | What it does |
| --- | --- | --- |
| `id` | `string` | Stable address for the node. Engines target it and build artifacts diff on it, so treat a rename as a breaking change. Optional: a node without one takes an id from where it sits, which is what keeps branches and loops from forcing you to invent names. Two nodes claiming one id is an error rather than a race. |
| `title` | `string` | Heading for the list. Renderers fall back to their own wording. |
| `derivers` | `DeriverInvocation[]` | Values the engine computes before the node resolves, written to `derived.*` and readable from a template token. Built with `derive()`. These survive publishing and run per document — use them for anything computed from request data. `useDeriver` runs one during the build instead. |

## Writing one

```tsx
import { TableOfContents } from "docxcelerate/template";

export const Contents: TableOfContents = () => (
  <TableOfContents id="contents" title="What is in this document" />
);
```

It composes like any other node, and resolves in preview builds, engine builds
and tests the same way. Placed directly in a template it needs no component of
its own — `<TableOfContents id="contents" title="…" />` is the whole thing.

## What is missing is downstream

The element places the marker and carries its title. Building the entries from
the surrounding section titles is a renderer's job, and neither the browser
preview nor the DOCX packer does it yet — both print the title and stop.

## Why place one now

It costs one line, and it starts printing entries the day the renderers build
them. The alternative — a hand-maintained list of section titles in a paragraph
— will be wrong within two releases.

If you would rather not ship a node that prints only a heading, leave it out.
Adding it later is equally cheap.

## Variants

### A titled marker

The element, and the title it carries into the document.

Source: `src/nodes/table-of-contents/basic.node.tsx`

```tsx
import { TableOfContents } from "docxcelerate/template";

/**
 * A heading standing in for the contents of the document around it.
 *
 * The shipped renderers print the title and stop — the entries themselves are
 * a renderer's job, and neither the browser preview nor the DOCX packer builds
 * them yet.
 */
export const Contents: TableOfContents = () => (
  <TableOfContents id="contents" title="What is in this letter" />
);
```

**What it resolves to**

```json
{
  "id": "contents",
  "kind": "tableOfContents",
  "title": "What is in this letter"
}
```

## Notes

- The node holds no children and reads nothing at build time.
- `title` is optional; renderers fall back to their own wording.
