Layouts

Jumbo React Vite ships eight layout variants. Each is a React component that composes JumboLayoutProvider + JumboLayout with a specific configuration. The active layout is determined solely by which route the user is on.

How layouts work

Every layout follows this pattern:

  1. JumboLayoutProvider — supplies an initial LayoutOptions config and owns the layout state
  2. JumboLayout — renders the shell using header, sidebar, footer, and rightSidebar slots
  3. <Outlet /> — renders the matched page route inside the content area
tsx
// Pattern used by every layout variant
export function ExampleLayout() {
  return (
    <JumboLayoutProvider layoutConfig={myLayoutConfig}>
      <JumboLayout header={<Header />} footer={<Footer />} sidebar={<Sidebar />}>
        <Outlet />
      </JumboLayout>
    </JumboLayoutProvider>
  );
}

Layout variants

LayoutRoute prefixSidebarHeaderFooterNotes
StretchedLayout/Persistent, 240pxFixed, 80pxVisibleDefault layout; includes Customizer
Demo1Layout/demo-1None (hide: true)Fixed, 100pxVisibleHeader-only navigation
Demo2Layout/demo-2Temporary (drawer)spreadOutVisibleMobile-style overlay sidebar
Demo3Layout/demo-3PersistentFixedHiddenRight sidebar region enabled
Demo4Layout/demo-4PersistentFixedHiddenDemo3 variant with a HeroSection banner
SoloLayout/auth, /extra-pagesNoneNoneNoneMinimal shell for auth and error pages
SettingsLayout/user/settings/*NoneNoneNoneNested layout for settings subtree
NewLayout1/new-layoutCustomCustomCustomExtensible scaffold for new layouts

StretchedLayout (default)

The application default. Mounts the Customizer settings drawer and a redirect from / to /dashboards/misc.

tsx
// src/layouts/StretchedLayout/StretchedLayout.tsx
export function StretchedLayout() {
  const location = useLocation();
  return (
    <JumboLayoutProvider layoutConfig={defaultLayoutConfig}>
      <JumboLayout
        header={<Header />}
        footer={<Footer />}
        sidebar={<Sidebar menus={getMenus()} />}
      >
        {location.pathname === '/' && <Navigate to='/dashboards/misc' />}
        <Outlet />
        <CustomizerSettings />
        <CustomizerButton />
      </JumboLayout>
    </JumboLayoutProvider>
  );
}

SoloLayout

Minimal layout with no navigation. Used for /auth and /extra-pages routes.

tsx
// src/layouts/SoloLayout/SoloLayout.tsx
export function SoloLayout() {
  return (
    <JumboLayoutProvider layoutConfig={{ /* all regions hidden */ }}>
      <Outlet />
    </JumboLayoutProvider>
  );
}

The sidebar behavior is controlled by the variant and view options in LayoutOptions.sidebar:

VariantBehavior
SIDEBAR_VARIANTS.PERSISTENTSidebar stays mounted and pushes page content when open/closed
SIDEBAR_VARIANTS.TEMPORARYOverlay drawer that closes on outside click (Demo2Layout)
SIDEBAR_VARIANTS.PERMANENTAlways visible; cannot be toggled
ViewBehavior
SIDEBAR_VIEWS.FULLFull sidebar showing icons + text labels
SIDEBAR_VIEWS.MINICollapsed sidebar showing icons only (80px wide)

Toggle the view at runtime using useJumboLayout().setSidebarOptions().

Creating a new layout

  1. Create the layout directory and files

    src/layouts/MyLayout/
      MyLayout.tsx
      Header.tsx
      Sidebar.tsx
      menus.ts
      index.ts
    
  2. Define a layout config

    typescript
    // src/layouts/MyLayout/_config.ts
    import { SIDEBAR_VARIANTS, SIDEBAR_VIEWS } from '@jumbo/utilities/constants';
    import type { LayoutOptions } from '@jumbo/types';
     
    export const myLayoutConfig: LayoutOptions = {
      sidebar: {
        variant: SIDEBAR_VARIANTS.PERSISTENT,
        view: SIDEBAR_VIEWS.FULL,
        width: 260,
        minWidth: 64,
        drawerBreakpoint: 'lg',
      },
      header: { fixed: true, sx: { height: 72 } },
      footer: { hide: true },
      root: {},
      content: { sx: { py: 3 } },
      wrapper: {},
      main: {},
    };
  3. Build the layout component

    tsx
    // src/layouts/MyLayout/MyLayout.tsx
    import { JumboLayout, JumboLayoutProvider } from '@jumbo/components';
    import { Outlet } from 'react-router-dom';
    import { myLayoutConfig } from './_config';
    import { Header } from './Header';
    import { Sidebar } from './Sidebar';
    import { getMenus } from './menus';
     
    export function MyLayout() {
      return (
        <JumboLayoutProvider layoutConfig={myLayoutConfig}>
          <JumboLayout header={<Header />} sidebar={<Sidebar menus={getMenus()} />}>
            <Outlet />
          </JumboLayout>
        </JumboLayoutProvider>
      );
    }
  4. Register the route

    typescript
    // src/routes/index.tsx
    import { MyLayout } from '@/layouts/MyLayout';
     
    // Add to the routes array:
    {
      path: '/my-layout',
      element: <MyLayout />,
      children: generateChildRoutes(demoRoutes, '/my-layout'),
    },