Skip to content

Layout

IAppShell

The page frame: header, sidebar, main and footer. Every slot takes whatever you put in it — navigation, account menu and routing stay yours, and ISidebar works with or without the shell.

NNorthwind

Row 1

Row 2

Row 3

Row 4

Row 5

Row 6

Row 7

Row 8

Row 9

Row 10

Row 11

Row 12

Version 1.4.0

Each of header, sidebar and footer is rendered only when you fill it, so a shell with just a header is a header and a content column, with no empty rails left behind.

Two scroll models

scroll picks between two layouts.

main, the default, pins the shell to the viewport and scrolls only the content column. The header and sidebar never move — what a data app wants.

page scrolls the document, with a sticky header and a sticky sidebar. Anchor links and the browser's scroll restoration work in this mode, so content and marketing pages want it. Being sticky rather than fixed, the sidebar travels up with the end of the body and the footer pushes it off screen.

Header

Row 1

Row 2

Row 3

Row 4

Row 5

Row 6

Row 7

Row 8

Row 9

Row 10

Row 11

Row 12

Version 1.4.0

The shell itself is the scroll container here, and the header sticks within it.

page mode sizes its sidebar against 100svh, so the boxed demo above overrides three values to keep the rail inside its frame:

vue
<IAppShell
  scroll="page"
  :ui="{
    root: 'h-72 min-h-0 overflow-y-auto',
    body: 'flex-none',
    sidebar: 'h-[calc(18rem-var(--iryx-shell-header-height,0px))] max-h-none',
  }"
>

A full-page shell needs none of that.

In page mode the shell measures its own header and publishes the height as --iryx-shell-header-height. Use that variable to offset anything you stick below the header yourself.

Northwind

Row 1

Row 2

Row 3

Row 4

Row 5

Row 6

Version 1.4.0

sidebarPosition moves the column; ISidebar's own side decides which edge carries its border. Set both.

Without a sidebar the shell is a header, a content column and the footer.

Northwind

Row 1

Row 2

Row 3

Row 4

Row 5

Row 6

Row 7

Row 8

Version 1.4.0

In main mode the footer is pinned below the scrolling column, so it stays visible however long the page is. In page mode it sits at the end of the document, where a footer normally lives.

Props

PropTypeDefaultDescription
asstring'div'Element or component to render as
scroll'main' | 'page''main'Scroll the content column, or the document
sidebarPosition'left' | 'right''left'Which side the sidebar rail sits on
unstyledbooleanDrop built-in classes
classstringMerged with the built-in classes
ui{ root?, header?, body?, sidebar?, main?, footer? }Per-slot class overrides

Slots

SlotWhen to use it
defaultThe page itself, inside <main>
headerApp bar. Measured in page mode to position the sticky sidebar
sidebarThe navigation rail — usually ISidebar
footerPinned below the content in main mode, at the end of the document in page mode

Pair it with IContainer for the content width and IPageHeader for the title row.