Responsive shell for your application with header and navbar


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

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

Responsive styles

Open responsive example in new tab
import { useState } from 'react';
import { AppShell, Burger, Header, MediaQuery, Navbar, Text, useMantineTheme } from '@mantine/core';
function Demo() {
const [opened, setOpened] = useState(false);
const theme = useMantineTheme();
return (
// navbarOffsetBreakpoint controls when navbar should no longer be offset with padding-left
// fixed prop on AppShell will be automatically added to Header and Navbar
// Breakpoint at which navbar will be hidden if hidden prop is true
// Hides navbar when viewport size is less than value specified in hiddenBreakpoint
// when viewport size is less than navbar width is 100%
// viewport size > – width is 300px
// viewport size > theme.breakpoints.lg – width is 400px
width={{ sm: 300, lg: 400 }}
<Text>Application navbar</Text>
<Header height={70} padding="md">
{/* You can handle other responsive styles with MediaQuery component or createStyles function */}
<div style={{ display: 'flex', alignItems: 'center', height: '100%' }}>
<MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
onClick={() => setOpened((o) => !o)}
<Text>Application header</Text>
<Text>Resize app to see responsive navbar in action</Text>

Navbar component

Navbar can be used outside of AppShell context:

<Navbar height={600} padding="xs" width={{ base: 300 }}>
<Navbar.Section><Brand /></Navbar.Section>
<Navbar.Section grow mt="lg"><MainLinks /></Navbar.Section>
<Navbar.Section><User /></Navbar.Section>


{/* 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 section</Navbar.Section>
{/* Last section with normal height (depends on section content) */}
<Navbar.Section>Last section</Navbar.Section>

Responsive width

// Base width – used when viewport is larger than theme.breakpoints.lg
base: 400,
breakpoints: {
// When viewport is smaller than theme.breakpoints.lg and larger than
lg: 300,
// When viewport is smaller than
sm: '100%',

Fixed position

To make Navbar fixed (like in Mantine docs) set fixed and position props:

<Navbar fixed position={{ top: 0, left: 0 }} />

Navbar with custom scrollbars

You can use ScrollArea component with Navbar.Section, set grow property and replace root element with ScrollArea component:

import { Navbar, ScrollArea } from '@mantine/core';
function Demo() {
return (
<Navbar height={600} padding={10} width={{ base: 300 }}>
<Navbar.Section mt="xs"><Brand /></Navbar.Section>
sx={{ paddingLeft: 10, paddingRight: 10 }}
{/* scrollable content here */}
<Navbar.Section><User /></Navbar.Section>

Wrapping Navbar and Header components

AppShell component requires Navbar and Header components to be direct children at navbar and header props. If you want to wrap Navbar component with your own custom component you will need to pass props to navbar and header:

import { AppShell, Navbar, NavbarProps } from '@mantine/core';
function CustomNavbar(props: NavbarProps) {
return <Navbar {...props}>Custom navbar</Navbar>;
function App() {
return (
<AppShell navbar={<CustomNavbar width={{ base: 300 }} height={500} padding="xs" />}>
App content

Semantic elements

  • Both Header and Navbar components root element is nav
  • AppShell wraps content with main tag – !important do not use main tag inside AppShell
Build fully functional accessible web applications faster than ever
Your feedback is most valuable contribution to the project, please share how you use Mantine, what features are missing and what is done good
Leave feedback