AppShell

Responsive shell for your application with header and navbar
Import

Usage

AppShell is a layout component that can be used to create a common Header - Navbar - Footer - Aside - Content layout pattern. AppShell, Header, Footer, Aside and Navbar components include bare minimum default styles to simplify customization. View full source code

Your application goes here
import { AppShell, Navbar, Header } from '@mantine/core';
function Demo() {
return (
<AppShell
padding="md"
navbar={<Navbar width={{ base: 300 }} height={500} p="xs">{/* Navbar content */}</Navbar>}
header={<Header height={60} p="xs">{/* Header content */}</Header>}
styles={(theme) => ({
main: { backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0] },
})}
>
{/* Your application here */}
</AppShell>
);
}

Responsive styles

Open responsive example in new tab
import { useState } from 'react';
import {
AppShell,
Navbar,
Header,
Footer,
Aside,
Text,
MediaQuery,
Burger,
useMantineTheme,
} from '@mantine/core';
export default function AppShellDemo() {
const theme = useMantineTheme();
const [opened, setOpened] = useState(false);
return (
<AppShell
styles={{
main: {
background: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0],
},
}}
navbarOffsetBreakpoint="sm"
asideOffsetBreakpoint="sm"
navbar={
<Navbar p="md" hiddenBreakpoint="sm" hidden={!opened} width={{ sm: 200, lg: 300 }}>
<Text>Application navbar</Text>
</Navbar>
}
aside={
<MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
<Aside p="md" hiddenBreakpoint="sm" width={{ sm: 200, lg: 300 }}>
<Text>Application sidebar</Text>
</Aside>
</MediaQuery>
}
footer={
<Footer height={60} p="md">
Application footer
</Footer>
}
header={
<Header height={{ base: 50, md: 70 }} p="md">
<div style={{ display: 'flex', alignItems: 'center', height: '100%' }}>
<MediaQuery largerThan="sm" styles={{ display: 'none' }}>
<Burger
opened={opened}
onClick={() => setOpened((o) => !o)}
size="sm"
color={theme.colors.gray[6]}
mr="xl"
/>
</MediaQuery>
<Text>Application header</Text>
</div>
</Header>
}
>
<Text>Resize app to see responsive navbar in action</Text>
</AppShell>
);
}

Alt layout

To place Navbar and Aside components above Header and Footer, set layout="alt" on AppShell.

Open alt layout example in new tab

hidden prop

To hide all AppShell components and render only children set hidden prop:

import { AppShell, Navbar, Header } from '@mantine/core';
function Demo() {
// Navbar and Header will not be rendered when hidden prop is set
return (
<AppShell navbar={<Navbar />} header={<Header />} hidden>
App content
</AppShell>
);
}

Navbar and Aside components

Navbar and Aside components can be used outside of AppShell context (View full source code):

import { Navbar } from '@mantine/core';
function Demo() {
return (
<Navbar height={600} p="xs" width={{ base: 300 }}>
<Navbar.Section>{/* Header with logo */}</Navbar.Section>
<Navbar.Section grow mt="md">{/* Links sections */}</Navbar.Section>
<Navbar.Section>{/* Footer with user */}</Navbar.Section>
</Navbar>
);
}

Navbar.Section and Aside.Section

import { Navbar } from '@mantine/core';
function Demo() {
// Same can be applied to Aside component with Aside.Section component
return (
<Navbar>
{/* First section with normal height (depends on section content) */}
<Navbar.Section>First section</Navbar.Section>
{/* Grow section will take all available space that is not taken by first and last sections */}
<Navbar.Section grow>Grow section</Navbar.Section>
{/* Last section with normal height (depends on section content) */}
<Navbar.Section>Last section</Navbar.Section>
</Navbar>
);
}

Responsive width

import { Navbar } from '@mantine/core';
function Demo() {
// Same can be applied to Aside component
return (
<Navbar
width={{
// When viewport is larger than theme.breakpoints.sm, Navbar width will be 300
sm: 300,
// When viewport is larger than theme.breakpoints.lg, Navbar width will be 400
lg: 400,
// When other breakpoints do not match base width is used, defaults to 100%
base: 100,
}}
>
Application navbar
</Navbar>
);
}

Static position

To make Navbar or Aside static, set fixed={false}:

import { Navbar } from '@mantine/core';
function Demo() {
return (
<Navbar fixed={false} position={{ top: 0, left: 0 }}>
Application navbar
</Navbar>
);
}

Custom scrollbars

Navbar.Section and Aside.Section components can be used with ScrollArea component (View full source code):

import { Navbar, ScrollArea } from '@mantine/core';
function Demo() {
return (
<Navbar height={600} p="xs" width={{ base: 300 }}>
<Navbar.Section mt="xs">{/* Header with logo */}</Navbar.Section>
<Navbar.Section grow component={ScrollArea} mx="-xs" px="xs">
{/* scrollable content here */}
</Navbar.Section>
<Navbar.Section>{/* Footer with user */}</Navbar.Section>
</Navbar>
);
}

Semantic elements

  • Header root element is header
  • Navbar root element is nav
  • Footer root element is footer
  • Aside root element is aside
  • AppShell wraps content with main tag – !important do not use main tag inside AppShell

AppShell component props

NameTypeDescription
aside
ReactElement<any, string | JSXElementConstructor<any>>
<Aside /> component
asideOffsetBreakpoint
number | "xs" | "sm" | "md" | "lg" | "xl"
Breakpoint at which Aside component should no longer be offset with padding-right, applicable only for fixed position
children *
ReactNode
AppShell content
fixed
boolean
true to switch from static layout to fixed
footer
ReactElement<any, string | JSXElementConstructor<any>>
<Footer /> component
header
ReactElement<any, string | JSXElementConstructor<any>>
<Header /> component
hidden
boolean
true to hide all AppShell parts and render only children
layout
"default" | "alt"
Determines how Navbar and Aside components are positioned relative to Header and Footer components
navbar
ReactElement<any, string | JSXElementConstructor<any>>
<Navbar /> component
navbarOffsetBreakpoint
number | "xs" | "sm" | "md" | "lg" | "xl"
Breakpoint at which Navbar component should no longer be offset with padding-left, applicable only for fixed position
padding
number | "xs" | "sm" | "md" | "lg" | "xl"
Content padding
zIndex
ZIndex
zIndex prop passed to Navbar and Header components

Navbar component props

NameTypeDescription
children *
ReactNode
Navbar content
fixed
boolean
Set position to fixed
height
string | number
Component height
hidden
boolean
Set to true to hide component at hiddenBreakpoint
hiddenBreakpoint
number | "xs" | "sm" | "md" | "lg" | "xl"
Breakpoint at which component will be hidden if hidden prop is true
position
HorizontalSectionPosition
Position for fixed variant
width
Partial<Record<string, string | number>>
Component width with breakpoints
withBorder
boolean
Determines whether the element should have border
zIndex
ZIndex
z-index

Header component props

NameTypeDescription
children *
ReactNode
Header content
fixed
boolean
Changes position to fixed, controlled by AppShell component if rendered inside
height *
VerticalSectionHeight
Component height with breakpoints
position
VerticalSectionPosition
Control top, left, right or bottom position values, controlled by AppShell component if rendered inside
withBorder
boolean
Determines whether the element should have border
zIndex
ZIndex
z-index

Aside component props

NameTypeDescription
children *
ReactNode
Aside content
fixed
boolean
Set position to fixed
height
string | number
Component height
hidden
boolean
Set to true to hide component at hiddenBreakpoint
hiddenBreakpoint
number | "xs" | "sm" | "md" | "lg" | "xl"
Breakpoint at which component will be hidden if hidden prop is true
position
HorizontalSectionPosition
Position for fixed variant
width
Partial<Record<string, string | number>>
Component width with breakpoints
withBorder
boolean
Determines whether the element should have border
zIndex
ZIndex
z-index

Footer component props

NameTypeDescription
children *
ReactNode
Footer content
fixed
boolean
Changes position to fixed, controlled by AppShell component if rendered inside
height *
VerticalSectionHeight
Component height with breakpoints
position
VerticalSectionPosition
Control top, left, right or bottom position values, controlled by AppShell component if rendered inside
withBorder
boolean
Determines whether the element should have border
zIndex
ZIndex
z-index

AppShell component Styles API

NameStatic selectorDescription
root.mantine-AppShell-rootRoot element, wraps Navbar, Header and content
body.mantine-AppShell-bodyAppShell body, contains Navbar and main element
main.mantine-AppShell-mainAppShell main element, contains content