The NavAnchor component is used throughout publication pages to create section anchors for the sidebar navigation. It could be replaced with plain HTML anchor elements, reducing the component abstraction.

Current behavior

NavAnchor does three things:

  1. Renders a <div> with an id attribute for anchor linking
  2. Registers itself with the sidebar Nav component via addItem()/removeItem() (from Nav.svelte)
  3. Tracks its DOM position via use:updateTopPosition action for scroll-spy behavior

Usage pattern:

<NavAnchor id="section-id" name="Section Name"></NavAnchor>
<h2>Section Name</h2>

Goal

Replace with plain anchors, e.g.:

<h2 id="section-id">Section Name</h2>

Challenge: sidebar navigation

The key complexity is that NavAnchor is not just an anchor -- it registers with the sidebar Nav for table-of-contents generation and scroll-spy. Removing NavAnchor requires an alternative way to:

  • Discover section headings for the sidebar table of contents
  • Track scroll position to highlight the active section

Possible approaches

Option A: DOM-based heading discovery

Nav component queries the DOM for headings with id attributes (e.g. h2[id]) and builds the TOC automatically. Uses IntersectionObserver for scroll-spy instead of manual position tracking.

Option B: Svelte action on headings

Create a use:navSection action that replaces NavAnchor's registration logic. Headings become <h2 id="foo" use:navSection>.

Option C: Keep registration, lose the component

Move the anchor+registration into an action or into the heading elements directly, but still use the addItem/removeItem pattern from Nav.

Scope

NavAnchor is used in many pages across the codebase. This is a bulk replacement task.

  • All publication pages (via Publication wrapper pattern)
  • Feature pages
  • Todo pages
  • Standalone pages

Simpler anchors

Less abstraction, same result

A static site template built with SvelteKit.

Sveleton, 2025