Layout

Every AdminLTE 4 page follows the same skeleton: an .app-wrapper CSS-grid container holding a header, sidebar, main content region, and an optional footer. Body-level classes control fixed positioning and the responsive sidebar breakpoint.

The page skeleton

The four region classes inside .app-wrapper are positioned as grid areas — their order in the markup doesn't matter, the grid template places each by its class.

<body class="layout-fixed sidebar-expand-lg bg-body-tertiary">
  <div class="app-wrapper">

    <!-- Header -->
    <nav class="app-header navbar navbar-expand bg-body">
      <div class="container-fluid">
        <ul class="navbar-nav">
          <li class="nav-item">
            <a class="nav-link" data-lte-toggle="sidebar" href="#" role="button">
              <i class="bi bi-list"></i>
            </a>
          </li>
        </ul>
      </div>
    </nav>

    <!-- Sidebar -->
    <aside class="app-sidebar bg-body-secondary shadow" data-bs-theme="dark">
      <div class="sidebar-brand">
        <a href="#" class="brand-link">
          <span class="brand-text fw-light">My Dashboard</span>
        </a>
      </div>
      <div class="sidebar-wrapper">
        <nav class="mt-2">
          <ul class="nav sidebar-menu flex-column" data-lte-toggle="treeview" role="menu">
            <!-- nav items -->
          </ul>
        </nav>
      </div>
    </aside>

    <!-- Main content -->
    <main class="app-main">
      <div class="app-content-header">
        <div class="container-fluid">
          <div class="row">
            <div class="col-sm-6"><h3 class="mb-0">Dashboard</h3></div>
            <div class="col-sm-6">
              <ol class="breadcrumb float-sm-end">
                <li class="breadcrumb-item"><a href="#">Home</a></li>
                <li class="breadcrumb-item active" aria-current="page">Dashboard</li>
              </ol>
            </div>
          </div>
        </div>
      </div>
      <div class="app-content">
        <div class="container-fluid">
          <!-- page body: cards, tables, charts -->
        </div>
      </div>
    </main>

    <!-- Footer -->
    <footer class="app-footer">
      <div class="float-end d-none d-sm-inline">Anything you want</div>
      <strong>Copyright &copy; 2026 <a href="#">Your Company</a>.</strong>
    </footer>

  </div>
</body>

The four regions

ClassRole
.app-wrapperThe grid root. Defines header / sidebar / main / footer areas. Lives directly inside <body>.
.app-headerThe top bar. Use Bootstrap navbar classes (navbar navbar-expand bg-body). Houses the sidebar toggle.
.app-sidebarThe side rail. Always contains .sidebar-brand and .sidebar-wrapper.
.app-mainThe content region — contains .app-content-header (title strip) and .app-content (page body).
.app-footerOptional footer strip at the bottom of the wrapper.

Always wrap children of .app-content-header and .app-content in .container-fluid (or .container for capped width). Forgetting it makes content land flush against the screen edge.

Body layout option classes

Layout behaviour is controlled by classes on <body>:

ClassEffect
layout-fixedSidebar gets its own scrollbar; only .app-main scrolls with the page.
fixed-headerPins .app-header to the top; the sidebar pins too.
fixed-footerPins .app-footer to the bottom of the viewport.
sidebar-expand-{sm,md,lg,xl,xxl}Breakpoint at which the sidebar switches from off-canvas (mobile) to inline (desktop). lg is the demo default.
sidebar-miniCollapses the sidebar to an icon-only mini state.
sidebar-collapseCombined with sidebar-mini, starts the page with the mini sidebar already collapsed.
sidebar-without-hoverDisables auto-expand-on-hover for the mini sidebar.
layout-rtlMirrors the layout for right-to-left languages (also needs adminlte.rtl.css and dir="rtl").

These compose. The demo dashboards use class="layout-fixed sidebar-expand-lg bg-body-tertiary".

Responsive behaviour

At and above the sidebar-expand-* breakpoint, the sidebar is inline in the grid. Below it, the sidebar becomes off-canvas — hidden by default and slid in from the left on toggle. The sidebar-open (explicitly opened) and sidebar-collapse (closed) classes are managed automatically by the PushMenu plugin via data-lte-toggle="sidebar" — you don't write them yourself.

Don't mix .app-* classes with AdminLTE 3's .main-* naming (.wrapper, .main-header, etc.). They are not interchangeable.


AdminLTE 4 · HTML port Edit on GitHub