AdminLTE 4 for Symfony
June 29, 2026 Β· View on GitHub
AdminLTE 4 for Symfony
Official AdminLTE 4 integration for Symfony β Bootstrap 5.3, AssetMapper, Twig Components, a config-driven sidebar menu, SSR-safe dark mode, and an optional theme for EasyAdmin.
π Live demo Β· π Documentation
AdminLTE everywhere
Features
- π§© Twig Components β
<twig:Adminlte:Card>,<twig:Adminlte:SmallBox>, β¦ typed, documented, slot-aware. - π§ Config-driven sidebar menu β one array in
config/packages/adminlte.yaml, with automatic active-route detection and per-item security (permission). - π SSR-safe dark mode β Bootstrap 5.3
data-bs-theme, set before first paint (no flash), persisted tolocalStorage, follows the OS while onauto. - β‘ AssetMapper-first β no Webpack Encore, no Node build required. CDN works out of the box; AssetMapper is the production path.
- ποΈ Optional EasyAdmin theme β layer AdminLTE styling onto your EasyAdmin backend.
- π§± Symfony-native β
AbstractBundle, autoconfigured services, PHP 8.4, strict types, PHPStan + php-cs-fixer.
Requirements
| PHP | 8.4+ |
| Symfony | 8.1+ (also 7.4 LTS once stabilised) |
| EasyAdmin (optional) | 5.1+ |
Installation
composer require colorlibhq/adminlte-symfony
With Symfony Flex the bundle is registered automatically. Otherwise add it to config/bundles.php:
return [
// ...
ColorlibHQ\AdminLteBundle\AdminLteBundle::class => ['all' => true],
];
Configuration
Create config/packages/admin_lte.yaml (Symfony underscores the bundle name, so the config key is admin_lte):
admin_lte:
title: 'My Admin'
title_short: 'MA'
color_mode: auto # light | dark | auto
dashboard_route: app_dashboard
logo:
text: '<b>My</b>Admin'
image: '/build/logo.png' # optional
layout:
fixed_sidebar: true
sidebar_mini: true
sidebar_collapsed: false
footer:
copyright: 'Β© 2026 My Company'
version: 'v1.0.0'
menu:
- { label: 'Dashboard', route: 'app_dashboard', icon: 'bi bi-speedometer2' }
- { header: 'MANAGEMENT' }
- label: 'Users'
icon: 'bi bi-people'
permission: 'ROLE_ADMIN' # hidden unless granted (needs symfony/security-bundle)
children:
- { label: 'All users', route: 'app_user_index' }
- { label: 'Create', route: 'app_user_new', badge: 'new', badge_class: 'text-bg-success' }
- { label: 'Documentation', url: 'https://adminlte.io', icon: 'bi bi-book', target: '_blank' }
Menu item keys: label, header, route, route_params, url, target, icon, badge, badge_class, permission, children.
Usage
Extend the layout from any page (this is the Symfony-idiomatic equivalent of the other ports' DashboardLayout):
{% extends '@AdminLte/layout.html.twig' %}
{% block page_title %}Dashboard{% endblock %}
{% block body %}
<div class="row">
<div class="col-lg-3 col-6">
<twig:Adminlte:SmallBox title="150" text="New Orders" variant="primary" icon="bi bi-bag" url="#" />
</div>
</div>
<twig:Adminlte:Card title="Welcome" icon="bi bi-stars" variant="primary" outline collapsible>
Built with AdminLTE 4 Twig Components.
</twig:Adminlte:Card>
{% endblock %}
A complete example lives in templates/demo/dashboard.html.twig. Wire it up:
#[Route('/admin', name: 'app_dashboard')]
public function dashboard(): Response
{
return $this->render('@AdminLte/demo/dashboard.html.twig');
}
Components (35+)
Layout β Sidebar, SidebarNavItem (recursive), Topbar, Footer, ColorModeToggle. The dashboard layout itself is {% extends '@AdminLte/layout.html.twig' %}.
Widgets β Card, SmallBox, InfoBox, Alert, Callout, Progress, ProgressGroup, Timeline + TimelineItem, ProfileCard, DescriptionBlock, Breadcrumb, Ratings, Toast, Modal, Accordion + AccordionItem, Tabs, NavNotifications, NavMessages, NavTasks, CommandPalette (βK).
Forms β Button, Input, Select, Textarea, InputSwitch, InputColor, InputFile.
Every component is a Twig Component:
<twig:Adminlte:Card title="Sales" icon="bi bi-graph-up" variant="primary" collapsible>β¦</twig:Adminlte:Card>
<twig:Adminlte:SmallBox title="150" text="New orders" icon="bi bi-bag" url="#" />
<twig:Adminlte:Timeline><twig:Adminlte:TimelineItem icon="bi bi-bell" time="3m" header="Ping" /></twig:Adminlte:Timeline>
<twig:Adminlte:CommandPalette /> {# βK palette, indexed from your sidebar menu #}
This matches the component inventory of the Vue/React ports. A few heavy plugin wrappers (charts, datatables, rich editors) remain optional add-ons.
Dark mode
The <head> script in _color_mode_script.html.twig sets data-bs-theme before the body paints (no flash), persists the choice to localStorage, and tracks the OS preference while on auto. <twig:Adminlte:ColorModeToggle /> flips it via the exposed window.adminlteToggleColorMode(). A Stimulus alternative ships in assets/controllers/color-mode_controller.js.
Production assets (AssetMapper)
The CDN links in the layout's stylesheets/javascripts blocks make the bundle work with zero config. For production, serve assets locally:
php bin/console importmap:require bootstrap admin-lte bootstrap-icons/font/bootstrap-icons.min.css
// assets/app.js
import '@colorlibhq/adminlte-symfony/adminlte.js'; // Bootstrap + AdminLTE behaviour
Then override the layout blocks in your base template to emit {{ importmap('app') }} instead of the CDN tags.
EasyAdmin theme
Layer AdminLTE onto an existing EasyAdmin backend. Either copy the shipped override into your app:
templates/bundles/EasyAdminBundle/layout.html.twig β copy from this bundle
β¦or load the assets from your DashboardController:
public function configureAssets(): Assets
{
return Assets::new()
->addCssFile('https://cdn.jsdelivr.net/npm/admin-lte@4.0.2/dist/css/adminlte.min.css')
->addJsFile('https://cdn.jsdelivr.net/npm/admin-lte@4.0.2/dist/js/adminlte.min.js');
}
Note: this is an initial integration that applies AdminLTE styling to EasyAdmin's own layout. A fully restructured AdminLTE shell (sidebar/topbar/config menu) for EasyAdmin is being rolled out incrementally.
Development
composer install
composer check # php-cs-fixer (lint) + phpstan + phpunit
License
MIT Β© Colorlib & AdminLTE contributors.
