JavaScript Plugins Overview

AdminLTE ships seven JavaScript plugins as a single bundle (adminlte.js). Each one is exported from the package root, can be triggered via data-lte-* attributes for declarative use, and exposes a programmatic API for code-driven control.

At a glance
Plugin Data API Programmatic Documentation
PushMenu data-lte-toggle="sidebar" .toggle() / .expand() / .collapse() Reference
Treeview data-lte-toggle="treeview" on parent menu .toggle() / .open() / .close() Reference
CardWidget data-lte-toggle="card-collapse", card-remove, card-maximize .toggle() / .collapse() / .expand() / .remove() / .maximize() / .minimize() / .toggleMaximize() Reference
DirectChat data-lte-toggle="chat-pane" .toggle() Reference
FullScreen data-lte-toggle="fullscreen" .toggleFullScreen() / .inFullScreen() / .outFullscreen() Reference
Layout (auto-applied to <body>) .holdTransition(time) Reference
AccessibilityManager (helper function: initAccessibility()) .announce() / .focusElement() / .trapFocus() / .addLandmarks() Reference
Two ways to use them
1. Data API (declarative)

For most pages, the data API is enough — no JavaScript code required. Drop the right data-lte-* attribute on the trigger element and the bundle wires it up on page load:

<!-- Sidebar toggle -->
<button data-lte-toggle="sidebar"></button>

<!-- Card collapse / remove / maximize -->
<div class="card">
  <div class="card-header">
    <h3 class="card-title">Title</h3>
    <div class="card-tools">
      <button class="btn btn-tool" data-lte-toggle="card-collapse" aria-label="Collapse card">
        <i data-lte-icon="expand" class="bi bi-dash-lg"></i>
        <i data-lte-icon="collapse" class="bi bi-plus-lg"></i>
      </button>
    </div>
  </div>
  <div class="card-body"></div>
</div>

The bundle attaches all data-API listeners on DOMContentLoaded. Dynamically-injected elements still work for the PushMenu, CardWidget, and Treeview plugins, which use event delegation.

2. Programmatic (imperative)

When you need to control a plugin from your own code — eg. open the sidebar after a successful login, or expand a card on a route change — retrieve the instance the data API already created, or create one on demand (since 4.1):

// ESM (bundler import)
import { PushMenu, CardWidget } from "admin-lte"

// Sidebar: the data API creates the instance on load — just fetch it
const sidebar = document.querySelector(".app-sidebar")
PushMenu.getInstance(sidebar)?.expand()

// Card maximize: reuses the existing instance, or creates one
const card = document.querySelector("#chart-card")
CardWidget.getOrCreateInstance(card).maximize()

Or use the globals (UMD bundle, no build step):

<script>
  // The bundle assigns to window.adminlte
  adminlte.PushMenu.getInstance(document.querySelector(".app-sidebar"))?.expand()
</script>
Component lifecycle

Every component follows the same Bootstrap-style contract:

  • Component.getInstance(element) — the instance created for that element, or null.
  • Component.getOrCreateInstance(element, config?) — reuse or create (config only applies on creation).
  • instance.dispose() — unregister the instance; getInstance() returns null afterwards.

One instance is kept per element in a registry backed by a WeakMap, so instances are garbage-collected together with their elements (nothing to clean up on Hotwired Turbo navigations). The data API listens with delegated document-level handlers, which means toggles inside content inserted after page load — AJAX partials, Turbo Frames — work without any re-initialisation.

Listening to plugin events

Every plugin fires bubbling CustomEvents on its root element (the card, the nav item, the sidebar) — listen on document for global hooks or on the element itself for scoped ones. Actions with a “before” event are cancelable: call preventDefault() to veto them.

document.addEventListener("expanded.lte.card-widget", (e) => {
  console.log("Card expanded:", e.target)
})

// Veto card removal until the user confirmed
document.addEventListener("remove.lte.card-widget", (e) => {
  if (!confirm("Remove this card?")) {
    e.preventDefault()
  }
})
Event name reference
Plugin Before (cancelable) After Fired for
PushMenu open.lte.push-menu opened.lte.push-menu Sidebar expanding
PushMenu collapse.lte.push-menu collapsed.lte.push-menu Sidebar collapsing
Treeview expand.lte.treeview expanded.lte.treeview Submenu opening (after fires post-animation)
Treeview collapse.lte.treeview collapsed.lte.treeview Submenu closing (after fires post-animation)
Treeview load.lte.treeview Pre-opened submenu detected on page load
CardWidget expand.lte.card-widget expanded.lte.card-widget Card expanding (after fires post-animation)
CardWidget collapse.lte.card-widget collapsed.lte.card-widget Card collapsing (after fires post-animation)
CardWidget remove.lte.card-widget removed.lte.card-widget Card removal (the card leaves the DOM after removed)
CardWidget maximized.lte.card-widget Card maximized
CardWidget minimized.lte.card-widget Card minimized
DirectChat expanded.lte.direct-chat Contacts pane opened
DirectChat collapsed.lte.direct-chat Contacts pane closed
FullScreen maximized.lte.fullscreen Entered fullscreen
FullScreen minimized.lte.fullscreen Exited fullscreen
ColorMode changed.lte.color-mode Theme changed (detail: { theme, resolved }, fired on document)

All events bubble (since 4.1). The “after” events of animated actions fire when the animation completes, not when it starts.

Configuring via data attributes

Some plugins read config from data-* attributes on their target element:

<!-- Treeview — non-accordion (multiple submenus can be open at once) -->
<ul class="nav sidebar-menu" data-lte-toggle="treeview" data-accordion="false"></ul>

<!-- Treeview — custom animation speed -->
<ul class="nav sidebar-menu" data-lte-toggle="treeview" data-animation-speed="500"></ul>

<!-- Sidebar — opt into localStorage persistence (default: off) -->
<aside class="app-sidebar" data-enable-persistence="true"></aside>

<!-- Sidebar — override the mobile breakpoint -->
<aside class="app-sidebar" data-sidebar-breakpoint="768"></aside>

Each plugin’s reference page documents which attributes it supports.

CSS classes the plugins manage

The plugins toggle a small set of CSS classes that you can also style or react to:

Class Set by Where Meaning
sidebar-collapse PushMenu <body> Sidebar collapsed (desktop mini state, or mobile-closed)
sidebar-open PushMenu <body> Mobile sidebar explicitly opened by user
sidebar-mini PushMenu <body> Mini-sidebar mode active
menu-open Treeview .nav-item Submenu is currently expanded
collapsed-card CardWidget .card Card body/footer are collapsed
maximized-card CardWidget <html> and .card Card is in fullscreen mode
direct-chat-contacts-open DirectChat .direct-chat Contacts pane visible
hold-transition Layout <body> Transitions disabled briefly (during resize, etc.)
app-loaded Layout <body> Initial page-load animation finished
reduce-motion AccessibilityManager <body> OS prefers-reduced-motion detected
Production vs source

The plugins live in src/ts/ as TypeScript modules. The published dist/js/adminlte.js is a Rollup bundle of all seven, exporting them under a single adminlte namespace (UMD) or named imports (ESM).

If you only need one or two plugins and care about bundle size, importing individual modules from node_modules/admin-lte/src/ts/ will tree-shake — but you’ll need TypeScript in your toolchain.

Where to next
  • Detailed reference for each plugin (links in the table above)
  • Layout Blueprint — the structural classes the plugins operate on
  • Accessibility — keyboard navigation, focus trapping, ARIA helpers