Askr documentation
UI & Components

Application Chrome

Application Chrome: anatomy, keyboard behavior, state, and theming in Askr.

Example

import { Header, Main, Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel } from '@askrjs/themes/components';

<>
  <Header>Workspace</Header>
  <Sidebar><SidebarContent><SidebarGroup><SidebarGroupLabel>Projects</SidebarGroupLabel></SidebarGroup></SidebarContent></Sidebar>
  <Main><ProjectRoutes /></Main>
</>

Purpose

`@askrjs/themes` and `@askrjs/ui` don't ship an `application-chrome` component, so treat this page as a walkthrough of how to assemble a full app shell from pieces that already exist. The outer frame comes from `Shell`, `ShellNav`, and `ShellMain`; the major regions are built with `Header`, `Main`, `Aside`, and `Footer` (plus its `FooterSection`, `FooterLinks`, and `FooterLink` parts). Fill the navigation areas inside that frame with `Navbar`, `Sidebar`, `Breadcrumb`, and `Pagination`.

Install and import

```tsx import { Shell, ShellNav, ShellMain } from '@askrjs/themes/components'; import { Header } from '@askrjs/themes/components'; import { Main } from '@askrjs/themes/components'; import { Aside } from '@askrjs/themes/components'; import { Footer, FooterSection, FooterLinks, FooterLink } from '@askrjs/themes/components'; ``` There's no single "chrome" subpath — pull the pieces you need from the general components barrel and compose them yourself.

Live examples

The example composes the persistent frame around routed content: brand, primary navigation, and the actions that stay put while the page beneath them changes. Keep the chrome in a layout component registered on a route group rather than repeating it per page, so navigating within the group replaces only the routed region.

Anatomy

`Shell` is a layout alias (a flex container with no default direction), `ShellNav` is the same alias for a nav-shaped region, and `ShellMain` defaults to rendering as `<main>` with `grow` set so it fills remaining space. Around that, `Header`, `Main`, and `Aside` are semantic region wrappers, and `Footer` composes with `FooterSection`, `FooterTitle`, `FooterDescription`, `FooterLinks`, and `FooterLink` for a structured site footer. None of these enforce a particular arrangement — you decide whether nav sits above, beside, or inside the shell.

State model

These are pure layout components; none of them own state. Anything dynamic in your chrome — a collapsed sidebar, an open mobile nav, the active breadcrumb trail — is state you manage in your own app and pass down as props or conditional children, the same way you would with `Navbar`'s `collapseAt` or `Sidebar`'s open/closed props on those individual component pages.

Keyboard and accessibility

Because `Header`, `Main`, `Aside`, and `Footer` map to real HTML5 landmark elements, screen reader users get a sensible landmark structure for free as long as you don't nest them in ways that break that semantics (for example, don't put more than one unlabeled `<main>` on a page). Beyond that base, the chrome components add no keyboard behavior of their own — any focus management for things like a mobile nav toggle needs to come from whatever interactive primitive you compose them with.

Styling and tokens

Each region component carries its own `data-slot` and default class from the underlying `Block` layout primitive, so you can target `header`, `main`, `aside`, and `footer` slots directly in CSS. Because `Shell`/`ShellNav`/`ShellMain` are thin aliases over `Block`, they also accept `Block`'s layout props (`gap`, `padding`, `direction`, etc.) for adjusting spacing without writing custom CSS.

API

There's no unified "chrome" prop surface to document — each piece keeps its own component's props (`HeaderProps`, `MainProps`, `AsideProps`, `FooterProps`, plus the `Block`-derived layout props on `Shell`/`ShellNav`/`ShellMain`). Check each component's own page for its specific prop list rather than expecting a shared API here.

Edge cases

Because chrome is assembled from independent pieces, the easiest mistake is duplicating landmarks — for instance rendering `Main` inside `ShellMain` when you only need one, or using `Aside` for both a sidebar and unrelated supplementary content without distinguishing them with labels. Responsive collapse behavior (mobile nav, collapsible sidebar) has to be composed explicitly from `Navbar`'s `collapseAt` and `Sidebar`'s own props; the shell components themselves have no breakpoint logic.

See Sidebar, Menubar, and Navbar and Navigation Menu for the navigation pieces that typically live inside this shell, and Layout Primitives for the broader page-layout primitives (`Block`, `Container`, `Text`) that chrome usually wraps.