This page aligns with the Chirp guide: UI layers & shell regions (same concepts; Chirp owns thechirp.shell_regionsconstants).
Quick glossary
| Term | Meaning |
|---|---|
| App shell | Persistent layout fromchirpui/app_shell_layout.html or app_shell() + shell_outlet(): topbar, sidebar, #main wrapper. Not replaced on navigation; #page-content inside #mainswaps, while the document owns vertical scroll by default. |
| Page content | The document area:#page-content — what hx-select targets for boosted nav, provided by app_shell_layout.html or shell_outlet(). |
| Page chrome | Route-owned UI inside#page-content: titles, tabs, toolbars — not the global topbar. |
| Shell actions | ShellActions → shell_actions_bar, target #chirp-shell-actions. Route-scoped; updates via OOB. |
| Shell regions | Stableids updated by hx-swap-oob (e.g. chirp-shell-actions, chirpui-document-title). |
| Marketing site shell | Full-page scroll layout:site_shell() + site_header() + site_footer(). Use for landing pages, docs homes, marketing sites. Counterpart to app shell — same document-scroll philosophy, no sidebar. |
| Surface chrome | Visual frame of a component (surface, panel, bento): border, padding, scroll — not the app shell. |
| Navigation domain | The author-facing boundary declared in Chirp_layout.html via {# domain: name #}. swap_attrs()uses shared domain ancestry to choose the right swap target. |
Avoid: using "chrome" alone for the whole app frame — say app shell, site shell, or topbar/sidebar.
Chirpmount_pageslayouts
Filesystem_layout.html files that extend app_shell_layout should declare {# target: body #}, an explicit {# domain: ... #}, and {# outlet: main #} so Chirp can:
- decide which links should boost together from shared domain ancestry
- match
HX-Target: #mainfor intra-domain app-shell navigation - return HTML that still includes
#page-contentforhx-select
Minimal pattern:
{# target: body #}
{# domain: workspace #}
{# shell: workspace #}
{# outlet: main #}
{% extends "chirpui/app_shell_layout.html" %}
See the Chirp guide Filesystem routing for the routing-side contract.
chirp-ui responsibilities
app_shell_layout.html— Defines the shell DOM, registers no extra Python; pairs with Chirp’suse_chirp_ui(app).- Shell coherence script — Clears
#chirp-shell-actionsinhtmx:beforeSwapwhen the response includes a shell-actions OOB, so users never see one frame of new page + stale actions (htmx runs primary swap before OOB).
Response boundaries
Application pages normally use three nested HTMX targets:
| Boundary | Target | Owner |
|---|---|---|
| Shell navigation | #main |
full page response with#page-contentand any changed OOB shell regions |
| Section navigation | #page-root |
page chrome and inner content for route-tab clicks |
| Local tools | #page-content-inneror a named fragment target |
local fragment only, isolated from inherited shell selectors |
Server code should inspectHX-Targetbefore choosing a response shape. A
genericHX-Requestcheck is not enough: shell navigation and route-tab
navigation are both HTMX requests, but they have different owners.
Related docs
- Repo:
docs/UI-LAYERS.md(duplicate reference for editors) - Repo:
docs/SHELL-TABS-CONTRACT.md(route-tab and response-shape checklist) docs/LAYOUT-OVERFLOW.md— keeping the main column stabledocs/COMPONENT-OPTIONS.md— components; distinguishes surface chrome from shell