Metadata row
The metadata row is the strip under an article title: the published date, the updated date when it differs, the reading time, and on blog and TIL pages a copy-as-Markdown button, separated by slashes. One component consolidates what other design systems split into separate Timestamp and Readtime components. The kind link above the title is not part of this strip; it belongs to the page header’s kind row.
The row below is the component rendered with this page’s own dates:
When to use#
- Every dated page gets the same strip in the same order: copy button, published date, updated date, reading time, collection badge, tag pills — items toggle on and off, they never reorder
- The updated date appears only when it differs from the published date; the partial compares the two, so a page never shows a redundant “Updated” entry
- Section defaults do most of the work — blog pages get the copy button and reading time, TIL pages the copy button — so reach for
pageHeader:front matter only when a page genuinely deviates - Not a place for new item types: the strip is assembled by the shared partial, and pages never hand-write it
Implementation#
pageHeader:
showReadingTime: true
showCopyMarkdown: true
useLastmod: false{{/* Normal path: section defaults merged with pageHeader: front matter */}}
{{ partial "entry-title-block.html" . }}
{{/* Direct call when a layout picks the items itself */}}
{{ partial "page-header.html" (dict "page" . "showReadingTime" true "showCopyMarkdown" true) }}<div class="mt-[var(--space-s)] flex flex-wrap items-center gap-x-[var(--space-xs)] gap-y-[var(--space-2xs)]" data-pagefind-ignore>
<span class="meta">Published <time datetime="2026-08-16">2026.08.16</time></span>
<span class="meta" aria-hidden="true">/</span>
<span class="meta">Updated <time datetime="2026-08-16">2026.08.16</time></span>
<span class="meta" aria-hidden="true">/</span>
<span class="meta">4 min read</span>
</div>The row is the meta template inside layouts/partials/page-header.html, driven by layouts/partials/entry-title-block.html, which sets the section defaults and merges pageHeader: front matter overrides before delegating. The row renders only when at least one item is enabled. The date labels come from the publishedOn and updatedOn i18n keys, the reading time from readingTime. There is no JavaScript in the row itself — the copy button brings its own, documented on Copy as Markdown — and no separate CSS file; items share the .meta class in assets/css/site.css.
Options#
| Option | Purpose |
|---|---|
showMeta | Master toggle for the whole row on article-variant headers |
showDate, showLastmod | Published date; updated date when it differs from the published date |
useLastmod | Replaces both dates with a single updated date |
dateLabel, lastmodLabel | Text before each date, as an i18n key or a literal |
showReadingTime | Reading time from Hugo’s word count; also settable per page as show_reading_time |
showCopyMarkdown | Copy-as-Markdown button at the start of the row |
showTags | Tag pills at the end of the row |
Interface manifest
- Kind
- Component
- Category
- Data
- Status
- Implemented
- Implementation
- Partial:
layouts/partials/page-header.htmllayouts/partials/entry-title-block.htmlCSS:assets/css/site.cssi18n:publishedOnupdatedOnreadingTime
Accessibility#
- The row is a plain
<div>of<span class="meta">items — display text, not a landmark, and it needs no role - Dates are
<time>elements with a machine-readabledatetimeattribute (2026-08-16) behind the displayed house format (2026.08.16), and the labels are locale-aware through thepublishedOnandupdatedOni18n keys - Reading time is non-interactive display text needing no ARIA; the
/separators carryaria-hidden="true", so screen readers skip them - Keyboard: only interactive items take focus — the copy button, the collection badge link, the tag pills; a row of dates and reading time has no tab stops
- Avoid hand-writing the strip in a layout — the separator
aria-hiddenand the paireddatetimeformats stay correct only through the shared partial