Skip to content

App Page

Give every page of your app the same header and gutter, so each one starts at the same place.

import { AppPage } from '@youj/react'

Installation & usage

npm i @youj/react

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Put each page of your app in AppPage, inside your frame's content area. Build an app frame puts the sidebar, top bar, account menu and search around it. The in-app screens use it, so a page of your own sits beside them with the same header and the same edges.

import { AppPage, Button } from '@youj/react'

export function Invoices() {
  return (
    <AppPage title="Invoices" description="Everything you've billed this year." actions={<Button>New invoice</Button>} width="fill">
      {/* your sections */}
    </AppPage>
  )
}

width sets how far the body runs. page (the default) stops at 1280px at 100% scale and centers, so a wide screen gets margins. fill takes the whole width, for a dashboard, a table, a board or a canvas. readable stops at 1024px and centers, for a page that is one form, such as settings. A page of tables, cards or lists fills; cap a field's own width rather than the page's.

The page is a container, so what's inside lays out by the page's width rather than the window's: use @3xl: and @6xl: in your sections. The gutter is 16px, 24px from a 48rem page and 32px from 72rem; the frame's top bars (see Build an app frame) follow the same gutter.

Reference

Propstitle, description, actions, width…

Props

AppPage props
PropType
titleReactNode

The page's heading.

–
descriptionReactNode

A line under the title.

–
actionsReactNode

The header's buttons, at its end: a primary action, a range control, a menu.

–
headingLevel1 | 2 | 3

The title's heading level; your sections' titles sit one below it.

default 1

1
width'page' | 'fill' | 'readable'

How wide the body runs: page (1280px at 100% scale, centered), fill (all of it) or readable (1024px, centered, for a page that is one form).

default 'page'

'page'
classNamesPartial<Record<'header' | 'body', string>>

Extra classes for the header and for the body (the padded column that holds the header and your sections).

–
childrenReactNode

The page's sections, stacked on the page's gutter.

–
Other props pass through: extends ComponentProps<'div'>.

data-slot marks its parts: app-page, app-page-body, app-page-header, app-page-title, app-page-description and app-page-actions.

Reduced motionAppPage is static

Reduced motion

AppPage is static. Nothing changes under reduced motion.

AccessibilityHeading level, landmarks

Accessibility

  • The title is an h1 by default. Set headingLevel when the page sits under another heading, and give your sections the level below it.
  • AppPage draws no landmark of its own: the frame's main holds it. Under a top bar that already names the page, the frame's AppFrame (the copy-in frame-shell) hides the title visually and keeps it for screen readers, so the page still has its heading.