# Chapterize JS
> A zero-dependency library that adds an automatic, accessible table of contents to an existing page DOM. Configured with HTML attributes only. About 5 KB gzip including the optional marker styles. Works in every framework and on plain sites.
## Usage
- Script tag: `` (global `Chapterize`, auto-init; add `data-manual` to opt out).
- npm: `import 'chapterize-js/auto'` (auto-init, SSR-safe) or `import { init, chapterjs, refresh, destroy, slug } from 'chapterize-js'`.
- Frameworks: render `` and call `init()` once on the client after hydration (useEffect, onMounted, onMount, afterNextRender). DOM watching handles routes and re-renders. init() is idempotent.
## Attributes (on the nav unless noted)
- `data-chapter`: required; spies the same-page links inside.
- `data-chapter-build[="selector"]`: build a nested from headings; empty = `main h2, main h3`. Missing ids are generated (slugs keep accents, duplicates get -2, -3).
- `data-chapter-marker[="line|pill|minimal"]`: built-in gliding marker (constructed stylesheet in `@layer chapter`, CSP-safe).
- `data-chapter-offset="64"`: sticky header height. Default: the scroller's CSS `scroll-padding-top`.
- `data-chapter-hash="false"`: don't pushState `#id` on click (hash routers `#/`, `#!` are detected).
- `data-chapter-label` (heading): outline text. `data-chapter-ignore` (heading or container): exclude.
## Output
- Active link: `.is-active` + `aria-current="location"`; ancestors: `.is-trail`.
- Nav CSS variables: `--chapter-y`, `--chapter-h`, `--chapter-x`, `--chapter-w`, `--chapter-progress`.
- Marker inputs: `--chapter-color`, `--chapter-color-2`, `--chapter-width`, `--chapter-duration`, `--chapter-ease`, `--chapter-indent`, `--chapter-rail`, `--chapter-glow`, `--chapter-band`, `--chapter-radius`.
- Event: `chapter:change` (bubbles) with `detail { index, id, link, target, previous }`.
## API
- `init(options?)` → controller `{ instances, refresh(), destroy() }`. Options: `build`, `offset`, `marker`, `hash`, `observe` (default true), `root`.
- `chapterjs(nav, options?)` → instance `{ nav, links, targets, index, id, go(idOrIndex, behavior?), refresh(), marker(preset|false), destroy() }`.
- `refresh()` / `destroy()`: every instance at once (`destroy()` also stops DOM watching until the next `init()`).
- `slug(text, root?)` → the id the outline would generate. `version`, `defaults` (`{ marker, hash, observe }`, mutable).
- Shadow roots: `init()` does not watch them. Call `chapterjs(nav)` and `refresh()` after changes.
## Docs
- npm: https://www.npmjs.com/package/chapterize-js (0.1.0)
- README: https://github.com/byronjohnson/chapterize-js#readme