Show insets
Paint the safe areas orange so you can see exactly what the shell is padding.
AppShell pads the whole shell
One prop, and every fixed element respects the device. The header grows by the top inset so the status bar never sits on your logo; the tab bar grows by the bottom inset so the home indicator never covers a button.
This demo runs with safeArea on — that’s the extra breathing room you can see above the logo right now.
<AppShell safeArea>
Keep the top inset on a static header
A static header scrolls away with the page, so it normally gives its safe-area padding back too. Set forceSafeAreaTop to keep the top inset applied while the header is at rest — no content jump when the page settles at the top.
<Header behavior="static" forceSafeAreaTop />
SafeArea pads any region
For full-bleed regions — maps, carousels, video — wrap just that region and pick the edges it should respect. The live box below is wrapped in a SafeArea with left and right edges:
In portrait this phone reports 0px on the sides, so the dashed frame hugs the box. Rotate a real device to landscape and the box pulls in from the notch.
<SafeArea edges={["left", "right"]}>Where the numbers come from
The platform standard, on iOS and Android alike: the browser exposes the notch and home-indicator geometry through env(safe-area-inset-*) once the page opts in with viewport-fit=cover. The shell reads those values directly — this docs mockup merely simulates an iPhone’s numbers inside the frame, since a desktop browser reports 0.
env(safe-area-inset-top) /* viewport-fit=cover */
The static tab bar below sits on the bottom inset — toggle the overlay to see the 34px it reserves.