--- id: upr-2026-02-26--observablehq--framework--toc-sidebar-inject type: upr target_org: observablehq target_repo: framework title: "Add injectTocTop() utility for injecting elements into the TOC sidebar" status: draft domain: custodian related_workstream: contribution-tracking-sbom state_hub_contribution_id: null created: "2026-02-26" updated: "2026-02-28" local_component_path: "state-hub/dashboard/src/components/toc-sidebar.js" target_upstream_file: "src/client/toc.ts" upstream_pr_url: null --- # Upstream PR: Add injectTocTop() utility for injecting elements into the TOC sidebar ## Summary Propose adding an `injectTocTop(id, element)` utility to Observable Framework that allows dashboard pages to prepend arbitrary HTML elements at the top of the automatically-generated table-of-contents sidebar. This enables KPI cards, live status indicators, and other contextual widgets to live alongside the page's section links. ## Motivation Observable Framework generates a TOC sidebar from headings automatically, but provides no standard way to inject content into it from page JavaScript. As a result, every project that wants sidebar widgets must implement its own DOM manipulation workaround. By upstreaming a small, focused utility, the community gets a stable API for sidebar injection that doesn't depend on Observable Framework's internal DOM structure. ## Local Component **Path in this repo**: `state-hub/dashboard/src/components/toc-sidebar.js` **Origin story**: Created 2026-02-26 during implementation of the Decisions KPI dashboard (State Hub v0.2). The component provides two utilities: - `injectTocTop(id, element)`: remove-then-prepend to the TOC aside element - `withDocHelp(element, docPath)`: attaches a `?` button that opens a doc page as an iframe overlay ## Target Upstream Location **Repo**: `observablehq/framework` **File**: `src/client/toc.ts` (or a new `src/client/toc-inject.ts`) ## Draft PR Body ```markdown ## Summary Add `injectTocTop(id, element)` — a small utility for injecting custom elements at the top of the Observable Framework table-of-contents sidebar. ## Motivation Dashboard pages frequently need contextual widgets (KPI boxes, live status indicators, navigation aids) that belong alongside the TOC, not in the page content flow. Currently this requires each project to directly manipulate the `#observablehq-toc` DOM element, coupling page code to an internal DOM detail. `injectTocTop` provides a stable API for this pattern: ```js import {injectTocTop} from "observablehq:toc"; const myWidget = html`