Page header
Page header is the standard title block at the top of a page: a kind link naming the section, the title, a metadata row (dates, reading time, tags), and an optional description. It establishes section, title, metadata, and primary context without custom exceptions.
The header below is the component rendered with the brand site’s privacy page content:
When to use#
- Every page type gets the same block — kind link, title, metadata row, optional description — with no custom exceptions per page
- Keep alignment, width, and optional elements consistent across page types; vary through the documented options, never through new markup
- Adjust per page with
pageHeader:front matter and per layout by passing options to the partial
Implementation#
pageHeader:
kind: legalEntry
kindUrl: /legal/
dateLabel: publishedOn
showLastmod: true{{/* Normal path: kind, labels, and toggles derived from the section */}}
{{ partial "entry-title-block.html" . }}
{{/* Direct call when a layout controls everything itself */}}
{{ partial "page-header.html" (dict "page" . "kind" "Legal" "showLastmod" true) }}<header>
<div>
<p class="entry-kind-row" data-pagefind-ignore>
<a class="entry-kind entry-kind-link" href="/en/legal/">Legal</a>
</p>
<h1 class="article-heading"><span>Privacy</span></h1>
<div class="mt-[var(--space-s)] ..." data-pagefind-ignore>
<span class="meta">Published <time datetime="2026-07-11">2026.07.11</time></span>
</div>
</div>
</header>The Hugo partial is layouts/partials/page-header.html. Layouts call it through layouts/partials/entry-title-block.html, which picks the kind label and link from the page’s section, resolves i18n keys, and merges pageHeader: front matter before delegating. There is no JavaScript and no separate CSS file; the block relies on shared classes (entry-kind-row, article-heading, section-heading, meta) defined in assets/css/site.css.
Options#
| Option | Purpose |
|---|---|
kind, kindHref, noKindLink | Section label above the title: its text, its link target, or plain text unlinked |
variant | article (default) or any other value for section-style headings — see Variants |
title, description, showDescription | Override the page title; show the description under the metadata row |
showMeta, showDate, showLastmod, useLastmod | Toggle the metadata row and which dates it carries |
dateLabel, lastmodLabel | Text placed before the published and updated dates |
showReadingTime, showTags, showCopyMarkdown, showFeed | Extra items: reading time, tag pills, copy-as-Markdown button, RSS icon after the title |
headingClass, descriptionClass | Class overrides for the title and the description |
Variants#
Two heading variants exist. article (the default) uses the article-heading class and shows the metadata row. Any other value — entry-title-block.html passes split for taxonomy and term pages — uses section-heading, hides the metadata row by default, and styles the description as a page-intro lede.
Interface manifest
- Kind
- Component
- Category
- Layout
- Status
- Implemented
- Implementation
- Partial:
layouts/partials/entry-title-block.htmllayouts/partials/page-header.htmlCSS:assets/css/site.cssi18n:publishedOnupdatedOnreadingTimetagtagDescriptionblogEntryblogSeriesEntrytilEntrybookEntryreferenceEntrytalksEntrylegalEntrypublicationEntryresourcescontactEntrysitemapEntry
Accessibility#
- The block is a
<header>element holding the page’s single<h1>; the variants change the heading class, never the heading level - Dates render as
<time>elements with machine-readabledatetimeattributes; reading time is plain display text and needs no ARIA - The
/separators between metadata items carryaria-hidden="true", and the RSS icon link names the page througharia-labelwhile its SVG staysaria-hidden="true" - Keyboard: the kind link, tag pills, collection badge link, RSS link, and copy-as-Markdown button take focus in reading order; Tab moves through them and Enter activates (the button also takes Space)
- Avoid a second page header or demoting the title with
headingClass— a page keeps exactly one<h1>, which is why this page’s live demo swaps it for a<p>