apps/design-system/content/docs/ui-patterns/layout.mdx
Build every Studio page with PageContainer, optional page chrome (Page Breadcrumbs, Page Nav), PageHeader when you need a title block, and PageSection. These components handle width, spacing, and content structure so pages feel consistent across the app.
PageBreadcrumbs) at the top. Place it as a sibling above PageHeader
or page content — not inside PageHeader.PageNav directly under the breadcrumb row, aligned top
left. Also a sibling — not inside PageHeader.| Width | Use when |
|---|---|
small | Settings, forms, and focused configuration (including child pages under a settings parent) |
default | Lists, tables, and detail pages that stay readable without full viewport width |
full | Dense horizontal content: logs, code, editors, charts, or tables that need the viewport |
A route can mix widths across child pages (for example, a full-width parent with a small settings tab and a full logs tab).
PageHeader with PageHeaderMeta (icon, title, description, aside) only when that context helps
the user. Skip it when the work area is self-explanatory (for example, logs with filters and a
table).| Situation | Where actions go |
|---|---|
| Parent with sub navigation | PageBreadcrumbsActions on the breadcrumb row |
Child page with PageHeaderMeta and no filter row | PageHeaderAside |
| Table or list with a filter/search row | Right side of that row (not header aside) |
| Simple list with no filter row | PageHeaderAside or PageSectionAside |
| Compact chrome, no meta (for example logs) | Breadcrumb row or in-page controls (filter bar, toolbar) |
PageHeader title and the content is split into multiple PageSections, use
PageSectionTitle and PageSectionDescription to label each section (see Page
Section).Single-column configuration. Use size="small" or size="default" for both header and container. Group fields with PageSection.
<ComponentPreview name="page-layout-settings" description="Settings page with default width" align="start" className="p-0" padded={false} peekCode wide />
Page sub navigation sits below page breadcrumbs.
<ComponentPreview name="page-layout-auth-emails" description="Settings parent with sub navigation and child page headers" align="start" className="p-0" padded={false} peekCode wide />
Collections of objects (tables, triggers, functions). Default to size="default"; use full when columns need the width.
<ComponentPreview name="page-layout-list" description="List with filters — actions aligned with the filter row" align="start" className="p-0" padded={false} peekCode wide />
<ComponentPreview name="page-layout-list-simple" description="Simple list without filters — actions in PageHeaderAside" align="start" className="p-0" padded={false} peekCode wide />
Dense content split into sections. Use size="default" and PageSection with orientation="horizontal" where a summary sits beside content.
<ComponentPreview name="page-layout-detail" description="Detail page with horizontal sections" align="start" className="p-0" padded={false} peekCode wide />
Logs, code, editors, and other dense views. Use size="full". Keep the top compact: breadcrumbs, optional breadcrumb-row actions, then sub navigation when needed. Omit PageHeader when there is no title block. Page-level actions live on the breadcrumb row or in the content (filter bar, toolbar).
<ComponentPreview name="page-layout-full-width" description="Full-width logs layout without page title or description" align="start" className="p-0" padded={false} peekCode wide />
Some parents are full width because a child needs it. The parent chrome stays compact (breadcrumbs, actions, sub navigation). Each child picks its own container width: overview charts in full, settings in small, logs and code in full without extra outer padding.
<ComponentPreview name="page-layout-edge-function" description="Full-width parent with small and full child containers" align="start" className="p-0" padded={false} peekCode wide />
small, default, full, …)