Section
Anchored content section with an editorial marker, title, subtitle and badges — the grid every documentation page is built on.
Playground
Playground Section
Try different options
<Section />01 Examples
Structuring a page
A numbered section
marker bare and the page counts — the literal is here because a demo section sits inside another section, and a nested one claims no number.01 Customization
slotClasses, preset and unstyled
Section content goes here.
<Section
id="demo-basic"
marker="01"
headingLevel={4}
title="Customization"
subtitle="slotClasses, preset and unstyled"
>
<p class="text-text-secondary text-sm">Section content goes here.</p>
</Section>A heading level that is not the visual size
Still an h3
Primary type scale, third-level semantics
The outline sees an h3; the reader sees the 24px heading.
<Section
id="demo-levels"
headingLevel={3}
intent="primary"
title="Still an h3"
subtitle="Primary type scale, third-level semantics"
>
<p class="text-text-secondary text-sm">
The outline sees an <code>h3</code>; the reader sees the 24px heading.
</p>
</Section>Badges and a footer
Remote mode
Server-side sorting, filtering and pagination.
<Section
id="demo-badges"
headingLevel={4}
title="Remote mode"
badges={[{ text: 'beta', variant: 'soft', intent: 'warning' }]}
>
<p class="text-text-secondary text-sm">Server-side sorting, filtering and pagination.</p>
{#snippet footerSnippet()}
<p class="text-text-tertiary text-sm">
Requires an endpoint that accepts the query state.
</p>
{/snippet}
</Section>02 Accessibility
Only a titled section is a region
The element is always <section>, but a browser exposes it as a region
landmark only once it has an accessible name — so the component points aria-labelledby at the heading it rendered, and omits the attribute entirely when
there is no heading to point at. A section carrying only a subtitle or badges is a container,
not a landmark, which is the honest answer: an unnamed region is a stop that announces nothing.
Choose the level, not the size
headingLevel sets the tag; intent sets the look. They are
separate on purpose: a subsection that needs h3 semantics can still carry the primary type scale, and nothing forces an author to break the outline to get the
size they want. Out-of-range levels are clamped to 1–6.
titleHidden keeps the heading, hides the header
A playground stage does not need a visible "Playground" heading, but its table-of-contents
entry still has to lead somewhere. titleHidden moves the whole header into the
screen-reader layer, so the heading stays in the outline and the section keeps its name. Do
not use it to quiet a section that simply has no title yet.
The marker is editorial
It renders as decorative text and is not part of the heading, so a screen reader announces "Examples", not "01 Examples". Nothing reads it back — the numbering is for the eye.
The page counts, not you
Write marker without a value and the section takes the next number in its page.
Insert a section and everything after it renumbers itself; a section nested inside another never
takes a number, so a demo inside a stage stays unstamped. A string still wins where a page numbers
by hand.
03 API Reference
Complete list of component properties and their configurations
Prop | Type | Default | Description | |
|---|---|---|---|---|
id required | string | — | Section ID for navigation anchors | |
badges | Array<{
text: string;
variant?: 'soft' | 'filled';
intent?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger';
}> | — | Badges property for the Section component | |
centered variant | falsetrue | false | Controls the centered behavior and appearance of the Section component. Available options: false, true. | |
children | Snippet | — | Main content snippet | |
class | string | — | Extra classes merged onto the root element. | |
footerSnippet | Snippet | — | Optional footer snippet (renders a semantic <footer>) | |
headingLevel | 1234 +2 more | 2 | Heading level for the section title, clamped to 1..6 | |
intent variant | defaultheroprimarysecondary | default | Controls the color theme and semantic meaning of the Section. Affects the overall appearance and user perception. Available options: default, hero, primary, secondary. | |
marker | string | boolean | — | Editorial marker before the title — a quieter monospace stamp.
Pass it bare (<Section marker …>) and the page numbers the section for
you: sections that ask for a marker are counted in render order within the
enclosing DocsLayout, so inserting one renumbers the rest by itself.
A section nested inside another never claims a number, which is what keeps
a <TypesReference> inside a playground stage unnumbered while the same
component at page level is numbered.
A string still wins, for the rare page that numbers by hand. Prefer the
bare form: the hand-written literals were wrong on four pages
(a duplicate 04, two skipped numbers, one page starting at 02) and
nothing reported it. | |
meta | string | — | Optional right-aligned monospace meta information in the title row
(e.g. "20 props", "6 recipes"). Renders as an editorial counter
next to the title with font-meta, so the information stays visually
subordinate to the section title. | |
size variant | lgmdsmxl | lg | Controls the dimensions, padding, and text size of the Section. Affects the component's physical footprint. Available options: lg, md, sm, xl. | |
slotClasses | Partial<Record<SectionSlots, string>> | — | Per-slot class overrides for internal elements. | |
subtitle | string | — | Subtitle text (property) | |
subtitleSnippet | Snippet | — | Custom subtitle snippet (overrides subtitle prop) | |
title | string | — | Title text. Renders as the section heading — this is deliberately **not**
the native title tooltip attribute, which is why it is omitted from the
inherited HTMLAttributes. | |
titleHidden | boolean | false | Keep the header in the screen-reader layer only — the section still gets a
real heading and a working aria-labelledby, it just does not draw one.
For sections whose purpose is obvious from what they contain but that carry
no heading in the design. The component playgrounds are the case this
exists for: the specimen sits directly under the page h1 and a
"Playground" heading above it would be redundant to a sighted reader —
while without one the table of contents offered a "Playground" entry
leading into an unnamed region, and heading navigation skipped the largest
interactive element on the page (measured on 57 pages, 2026-08).
Do not reach for it to quiet a section that simply has no title yet: a
hidden heading and a missing heading look the same in the markup and only
one of them is a decision. | |
titleSnippet | Snippet | — | Custom title snippet (overrides title prop) | |
unstyled | boolean | — | Strip all default styles; combine with slotClasses to rebuild from scratch. | |
...HTMLAttributes<HTMLElement> inherited | HTMLAttributes | — | HTML attributes (excluding: 'children' | 'title') | |
...SectionVariantProps variant | VariantProps | — | Styling variants from SectionVariantProps |
04 Types
Local type definitions used by this component.
Name | Kind | Category | Used by | Description | |
|---|---|---|---|---|---|
SectionProps | interface | props | 0 | Props interface for Section component | |
SectionVariantProps | type | variant | 1 | — | |
SectionSlots | type | variant | 0 | Slot names derived from the tv() config above — single source of truth for slotClasses. |
05 Installation
Import
import { Section } from '@urbicon-ui/docs';