Skip to content

SectionHeader

SectionHeader renders a lightweight section-level heading with optional subtitle, eyebrow label, badge, and action buttons. It is the within-section sibling of PageHeader, which is designed for page-level titles.

Use PageHeader for top-of-page titles. Use SectionHeader for headings inside cards, dashboard panels, and admin screens.

Bootstrap Reference

Bootstrap 5 Typography


Quick Start

from faststrap import SectionHeader, Button, Badge

SectionHeader(
    "Users",
    subtitle="Manage team members and permissions.",
    eyebrow="Admin",
    badge=Badge("New", variant="success"),
    actions=[Button("Add User", variant="primary")],
)

Visual Examples & Use Cases

1. Basic Section Header

Live Preview
Users
SectionHeader("Users")

2. With Subtitle and Eyebrow

Live Preview
Admin

Users

Manage team members and permissions.

SectionHeader(
    "Users",
    eyebrow="Admin",
    subtitle="Manage team members and permissions.",
)

3. With Badge and Actions

Live Preview

Users New

Manage team members.

SectionHeader(
    "Users",
    subtitle="Manage team members.",
    badge=Badge("New", variant="success"),
    actions=[Button("Add User", variant="primary")],
)

4. Small Size (h3)

Live Preview

Settings

SectionHeader("Settings", size="sm")

Practical Functionality

1. Inside a Card

Card(
    SectionHeader(
        "Recent Activity",
        eyebrow="Logs",
        actions=[Button("Refresh", variant="secondary", outline=True)],
    ),
    Card.Body(
        # ... activity list
    ),
)

2. Inside a Dashboard Grid

DashboardGrid(
    SectionHeader("Overview", subtitle="Key metrics for this week."),
    StatCard("Revenue", "$12K", "+5%"),
    StatCard("Users", "1.2K", "+12%"),
    cols=3,
)

3. With HTMX Actions

SectionHeader(
    "Items",
    actions=[
        Button("Add", variant="primary", hx_get="/items/new", hx_target="#modal"),
    ],
)

When to Use SectionHeader vs PageHeader

Component Use Case Heading Level
PageHeader Page-level title, first thing on the page h1/h2
SectionHeader Within-section heading, inside cards/panels h2/h3

Parameter Reference

Parameter Type Default Description
title str required Section title text.
subtitle str \| None None Muted supporting copy below the title.
eyebrow str \| None None Small uppercase label above the title.
badge Any \| None None Inline badge or status element beside the title.
actions Any \| list[Any] \| tuple[Any, ...] \| None None Right-aligned action content.
size str "md" Heading size: "sm" renders an h3, "md" renders an h2.
**kwargs Any {} Additional HTML/HTMX/data/ARIA attributes.

API Reference

faststrap.components.layout.section_header.SectionHeader(title, *, subtitle=None, eyebrow=None, badge=None, actions=None, size='md', **kwargs)

Render a section title area with optional subtitle and actions.

Lighter-weight sibling of PageHeader for within-section headings.

Parameters:

Name Type Description Default
title str

Section title text.

required
subtitle str | None

Optional muted description below the title.

None
eyebrow str | None

Optional small uppercase label above the title.

None
badge Any | None

Optional badge element to show beside the title.

None
actions Any | list[Any] | tuple[Any, ...] | None

Optional action buttons or components to show on the right.

None
size str

Heading size — sm renders an h3, md renders an h2.

'md'
**kwargs Any

Additional HTML attributes (cls, id, etc.).

{}

Returns:

Type Description
Div

FastHTML Div element with section header styling.

Source code in src/faststrap/components/layout/section_header.py
@register(category="layout")
@stable
def SectionHeader(
    title: str,
    *,
    subtitle: str | None = None,
    eyebrow: str | None = None,
    badge: Any | None = None,
    actions: Any | list[Any] | tuple[Any, ...] | None = None,
    size: str = "md",
    **kwargs: Any,
) -> Div:
    """Render a section title area with optional subtitle and actions.

    Lighter-weight sibling of `PageHeader` for within-section headings.

    Args:
        title: Section title text.
        subtitle: Optional muted description below the title.
        eyebrow: Optional small uppercase label above the title.
        badge: Optional badge element to show beside the title.
        actions: Optional action buttons or components to show on the right.
        size: Heading size — `sm` renders an `h3`, `md` renders an `h2`.
        **kwargs: Additional HTML attributes (cls, id, etc.).

    Returns:
        FastHTML Div element with section header styling.
    """
    user_cls = kwargs.pop("cls", "")

    size_map = {
        "sm": "h3",
        "md": "h2",
    }
    heading_tag = size_map.get(size, "h2")
    heading_cls = "mb-1" if size == "sm" else "mb-2"

    title_children: list[Any] = []
    if eyebrow:
        title_children.append(Span(eyebrow, cls="text-uppercase text-muted small fw-semibold"))

    heading_children: list[Any] = [title]
    if badge is not None:
        heading_children.append(Span(badge, cls="ms-2 align-middle"))
    title_children.append(_render_heading(Span(*heading_children), heading_tag))
    title_children[-1].cls = heading_cls

    if subtitle:
        title_children.append(P(subtitle, cls="text-muted mb-0"))

    children: list[Any] = [Div(*title_children)]
    if actions is not None:
        if isinstance(actions, (list, tuple)):
            action_children = list(actions)
        else:
            action_children = [actions]
        children.append(Div(*action_children, cls="d-flex flex-wrap gap-2 align-items-center"))

    attrs: dict[str, Any] = {
        "cls": merge_classes(
            "d-flex flex-column flex-lg-row align-items-lg-center justify-content-between gap-2 mb-3",
            user_cls,
        )
    }
    attrs.update(convert_attrs(kwargs))
    return Div(*children, **attrs)