heading-links
Adds clickable anchor links to headings with auto-generated IDs and click-to-copy URL support.
Overview
Wraps a content area and adds anchor link icons to headings. Hover a heading to reveal the link icon; click it to scroll, update the URL hash, and copy the link to clipboard.
Usage
Wrap any content containing headings. By default, h2 and h3 elements are processed.
Basic usage
<heading-links> <h2>Getting Started</h2> <p>Content here...</p> <h3>Installation</h3> <p>More content...</p></heading-links>
Attributes
| Attribute | Values | Default | Description |
|---|---|---|---|
levels | Comma-separated heading selectors | h2,h3 | Which heading levels to process |
Custom heading levels
<!-- Only process h2 headings --><heading-links levels="h2"> <h2>This gets an anchor</h2> <h3>This does not</h3></heading-links> <!-- Process h2, h3, and h4 --><heading-links levels="h2,h3,h4"> <h2>Anchor link</h2> <h3>Anchor link</h3> <h4>Anchor link</h4></heading-links>
Auto-generated IDs
Headings without an id attribute get one generated from their text content. Existing IDs are preserved. Generated IDs are limited to 50 characters and de-duplicated automatically.
ID handling
<!-- Existing IDs are preserved --><heading-links> <h2 id="custom-id">This keeps its ID</h2> <h3>This gets an auto-generated ID</h3></heading-links>
Events
| Event | Detail | Description |
|---|---|---|
heading-links:navigate | { id: string, url: string } | Fired when an anchor link is clicked |
Event listener
const el = document.querySelector('heading-links'); el.addEventListener('heading-links:navigate', (e) => { console.log('Navigated to:', e.detail.id); console.log('URL:', e.detail.url);});
Behavior
- Anchor icons appear on heading hover or focus
- Clicking an anchor scrolls smoothly to the heading, updates the URL hash, and copies the full URL to clipboard
- A brief checkmark icon confirms the copy succeeded
- A screen-reader announcement is made on successful copy
- Headings inside
<dialog>elements are skipped - A
MutationObserverwatches for dynamically added headings
Accessibility
- Each anchor has
aria-label="Link to [heading text]" - Headings are made focusable with
tabindex="-1"for keyboard navigation to anchored sections - Copy confirmation uses
role="status"witharia-live="polite" - Focus-visible styles on anchor links
Styling
The anchor uses the .heading-anchor class. It is hidden by default (opacity: 0) and revealed on hover/focus.
Custom styling
/* Custom anchor icon color */heading-links .heading-anchor { color: var(--color-primary);} /* Always show anchors (instead of hover-only) */heading-links .heading-anchor { opacity: 1;}
Related
<page-toc>— Table of contents generator (pairs well with heading-links)data-copy— Click-to-copy attribute