Anchor index

An anchor index is a labelled row of compact links that jumps to repeated sections of the current page. It is common on data-driven reference pages where each section has a count: letters, categories, regions, zones, or similar groups.

Example#

Jump to a section of this page:

Variants#

The partial has one visual pattern. A caller may omit the count, omit the visible lead-in label, or add a labelClass to an item label. These are content variations, not separate components. Use a filter row when controls change the dataset.

When to use#

  • The page has repeated sections and readers need to jump directly to one of them.
    • Common on data-driven reference pages where each section carries a count: letters, categories, regions, zones
  • Never for active filters.
    • A filter changes what is visible; an anchor index only moves the reader to an existing section. That job belongs to the filter row.
  • The visible label names both the destination and what the count means, for example “Jump to region (country or area counts):”

Implementation#

{{ partial "data-page/anchor-index.html" (dict "items" $anchorItems "ariaLabelKey" "m49Regions" "labelKey" "geographicRegionsAnchorIndexLabel") }}

Each item provides label, href, and optionally count:

dict "label" "Europe" "href" "#m49-region-150" "count" 52
<div class="not-prose flow-section">
  <p class="meta mb-[var(--space-2xs)]">Jump to region (country or area counts):</p>
  <nav class="anchor-index-list" aria-label="M49 regions">
    <a class="anchor-index-link" href="#m49-region-150"><span>Europe</span> <span class="anchor-index-count">52</span></a>
  </nav>
</div>
  1. The page or layout builds an items slice with label, href, and optional count.
  2. The partial returns nothing when items is empty.
  3. The partial resolves the visible label and aria-label from i18n when the *Key options are used.
  4. The partial emits plain fragment links. There is no JavaScript.
  5. Component CSS composes Style Dictionary colour, spacing, and type tokens into the links’ layout and states.

Options#

OptionPurpose
itemsSlice of dicts, each with label, href, and optional count and labelClass (required; nothing renders when empty)
labelKey / labelVisible lead-in label; use labelKey for published pages and label only for local prototypes
ariaLabelKey / ariaLabelRequired accessible name of the nav; use ariaLabelKey for published pages and ariaLabel only for local prototypes
classReplaces the default anchor-index-list class on the nav

Published callers must supply labelKey when they need a visible lead-in and must supply ariaLabelKey for the landmark name. Use a page-specific key based on the page or data filename, such as airlineCodesAnchorIndexLabel, workforceFrameworksAnchorIndexLabel, geographicRegionsAnchorIndexLabel, or internationalCountryCallingCodesAnchorIndexLabel, so the text is explicit and the partial never guesses context.

Interface manifest

Kind
Component
Category
Navigation
Status
Implemented
Implementation
Partial:layouts/partials/data-page/anchor-index.htmlCSS:assets/css/site.cssi18n:alphabeticalIndexcategoriescallingCodeZonesm49RegionsairlineCodesAnchorIndexLabelworkforceFrameworksAnchorIndexLabelgeographicRegionsAnchorIndexLabelinternationalCountryCallingCodesAnchorIndexLabelphoneticAlphabetAnchorIndexLabelusesCategoriesusesCategoryAnchorIndexLabel

Accessibility#

  • The row is a <nav> landmark of plain fragment links.
    • The visible lead-in label is a separate <p> before the nav, not the landmark’s name.
  • The accessible name comes from ariaLabel or ariaLabelKey, rendered as aria-label on the <nav>.
    • Always pass one so the row stays distinguishable from the page’s other navigation landmarks. The partial warns during the Hugo build when it is absent.
  • Each link keeps the section name as visible link text, with the optional count in its own anchor-index-count span as supplementary text
  • Keyboard: Tab reaches each link and Enter follows the fragment to its section
  • Avoid a count-only link. The count supplements the label and must never be the only text a link carries.