Theming & Dark Mode

AdminLTE for Drupal ships light and dark colour modes built on Bootstrap 5.3's data-bs-theme. The mode is applied before the first paint (no flash), persisted to the browser, and follows the OS preference while on auto. Customise further by sub-theming and overriding templates or libraries.

How dark mode works

A tiny inline script in html.html.twig resolves the colour mode before the stylesheet loads and sets data-bs-theme on <html>, preventing a flash of the wrong mode (mirrors AdminLTE core #6043):

<script>
  (() => {
    const STORAGE_KEY = 'lte-theme';
    const fallback = {{ default_color_mode|default('auto')|json_encode|raw }};
    let stored = null;
    try { stored = localStorage.getItem(STORAGE_KEY); } catch { /* private mode */ }
    const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
    /* …resolve to 'light' | 'dark'… */
    document.documentElement.setAttribute('data-bs-theme', resolved);
    document.documentElement.style.colorScheme = resolved;
  })();
</script>
  • The persisted value lives under localStorage['lte-theme'] — the same key shared with the Vue, React and Angular ports.
  • The fallback comes from the Default colour mode theme setting (light / dark / auto).
  • On auto, the script resolves to the OS preference via prefers-color-scheme until the user makes an explicit choice.

The navbar toggle

The navbar carries a [data-adminlte-theme-toggle] button. The adminlteThemeToggle behaviour in adminlte-drupal.js flips the mode, swaps the moon/sun icon, and persists the choice:

const applyMode = (mode) => {
  document.documentElement.setAttribute('data-bs-theme', mode);
  document.documentElement.style.colorScheme = mode;
  try { localStorage.setItem('lte-theme', mode); } catch { /* private mode */ }
};

The dark sidebar

The Dark sidebar setting renders the sidebar dark independently of the page mode by putting data-bs-theme="dark" on the <aside class="app-sidebar"> element in page.html.twig. Set it under theme settings.

Customising colours

AdminLTE 4 is built on Bootstrap 5.3 CSS variables, so override theme colours with standard Bootstrap custom properties — scoped to a mode if needed. Add the CSS via your sub-theme's library:

:root {
  --bs-primary: #6610f2;
  --bs-primary-rgb: 102, 16, 242;
}
[data-bs-theme="dark"] {
  --bs-body-bg: #14181f;
}

Sub-theming

To customise without editing the contrib theme, create a sub-theme with AdminLTE as its base and attach your own library:

# mytheme.info.yml
name: 'My AdminLTE'
type: theme
base theme: adminlte
core_version_requirement: ^10.3 || ^11
libraries:
  - mytheme/global
# mytheme.libraries.yml
global:
  css:
    theme:
      css/overrides.css: {}

From the sub-theme you can override any of AdminLTE's templates (copy a file from templates/ into your sub-theme's templates/) and add or override CSS/JS via your library. Run drush cr after changes so Drupal picks up the new template overrides.

Because the mode is set on <html> before the body paints, your colour overrides must be valid for both [data-bs-theme="light"] and [data-bs-theme="dark"] to avoid a mismatch when users switch.


AdminLTE 4 · Drupal port Edit on GitHub