Plugins
AdminLTE 4 for Laravel lazy-loads a handful of optional JavaScript libraries.
A plugin's assets are only emitted on pages that actually use it, keeping the
base layout lean. This is managed by the PluginManager singleton and the
@pluginStyles / @pluginScripts Blade directives.
How PluginManager works
PluginManager (src/Plugins/PluginManager.php) is registered as a singleton
seeded from the plugins array in config/adminlte.php. Because it is a
singleton, plugin state set during a request (for example by a component)
persists until the directives render.
Public API:
| Method | Description |
|---|---|
enable(string $plugin) |
Mark a plugin enabled for this request (only if it exists in config). |
disable(string $plugin) |
Mark a plugin disabled for this request. |
isEnabled(string $plugin) |
Whether the plugin is enabled (request override, else config enabled). |
has(string $plugin) |
Whether the plugin key exists in config. |
getCss(string $plugin) / getJs(string $plugin) |
Raw configured asset value when enabled, else null. |
getEnabledPlugins() |
All currently enabled plugins keyed by name. |
renderStyles() / renderScripts() |
HTML <link> / <script> tags for every enabled plugin. |
You can drive it directly from a view or service if needed:
@php app(\ColorlibHQ\AdminLte\Plugins\PluginManager::class)->enable('apexcharts'); @endphp
Config shape (css/js as string or array)
Each plugin is defined under the plugins key:
'plugins' => [
'apexcharts' => [
'enabled' => false,
'js' => 'vendor/apexcharts/apexcharts.min.js',
],
'jsvectormap' => [
'enabled' => false,
'css' => 'vendor/jsvectormap/jsvectormap.min.css',
'js' => [
'vendor/jsvectormap/jsvectormap.min.js',
'vendor/jsvectormap/maps/world.js',
],
],
],
enabled— whether the plugin loads by default on every page. Most ship asfalseand are turned on per-page by components.cssandjsaccept either a single string or an array of strings.renderStyles()/renderScripts()cast each to an array and emit one tag per file, in order. (Order matters — e.g. jsVectorMap loads the library first, then the world-map data file.)- A plugin may omit
cssorjsentirely (e.g. ApexCharts is JS-only).
All paths are passed through Laravel's asset() helper, so they resolve
relative to public/.
The @pluginStyles / @pluginScripts directives
These directives are registered in AdminLteServiceProvider and execute at
request time, not compile time:
Blade::directive('pluginStyles', fn () => "<?php echo app('...PluginManager')->renderStyles(); ?>");
Blade::directive('pluginScripts', fn () => "<?php echo app('...PluginManager')->renderScripts(); ?>");
The master layout places @pluginStyles in <head> and @pluginScripts at the
bottom of <body>. Because they evaluate during rendering, any plugin a
component enabled earlier in the same request is included.
Components auto-enable their plugins
Plugin-backed components call PluginManager::enable() in their constructor, so
simply using the component on a page emits the right assets — no config or manual
calls required:
| Component | Plugin enabled |
|---|---|
<x-adminlte-input-flatpickr> |
flatpickr |
<x-adminlte-input-tom-select> |
tom_select |
<x-adminlte-datatable> |
tabulator |
<x-adminlte-editor> |
quill |
<x-adminlte-chart> |
apexcharts |
<x-adminlte-vector-map> |
jsvectormap |
<x-adminlte-calendar> |
fullcalendar |
<x-adminlte-sortable> |
sortablejs |
<x-adminlte-kanban> |
sortablejs |
Bundled plugins
| Key | CSS | JS |
|---|---|---|
flatpickr |
vendor/flatpickr/flatpickr.min.css |
vendor/flatpickr/flatpickr.min.js |
tom_select |
vendor/tom-select/tom-select.bootstrap5.min.css |
vendor/tom-select/tom-select.complete.min.js |
tabulator |
vendor/tabulator-tables/tabulator.min.css |
vendor/tabulator-tables/tabulator.min.js |
quill |
vendor/quill/quill.snow.css |
vendor/quill/quill.min.js |
apexcharts |
— | vendor/apexcharts/apexcharts.min.js |
jsvectormap |
vendor/jsvectormap/jsvectormap.min.css |
vendor/jsvectormap/jsvectormap.min.js, vendor/jsvectormap/maps/world.js |
fullcalendar |
— | vendor/fullcalendar/index.global.min.js |
sortablejs |
— | vendor/sortablejs/sortablejs.min.js |
Note the config key for Tom Select is
tom_select(underscore).
How vendor files reach public/vendor
php artisan adminlte:install runs copyVendorFiles()
(src/Console/InstallCommand.php), which copies library files out of
node_modules into public/vendor. Keys are source paths relative to
node_modules; values are destination paths relative to public/vendor
(allowing a rename on copy). Missing sources are skipped silently.
From node_modules/... |
To public/vendor/... |
|---|---|
apexcharts/dist/apexcharts.min.js |
apexcharts/apexcharts.min.js |
jsvectormap/dist/jsvectormap.min.css |
jsvectormap/jsvectormap.min.css |
jsvectormap/dist/jsvectormap.min.js |
jsvectormap/jsvectormap.min.js |
jsvectormap/dist/maps/world.js |
jsvectormap/maps/world.js |
fullcalendar/index.global.min.js |
fullcalendar/index.global.min.js |
sortablejs/Sortable.min.js |
sortablejs/sortablejs.min.js |
admin-lte/dist/css/adminlte.rtl.min.css |
adminlte/css/adminlte.rtl.min.css |
The last entry is the RTL stylesheet loaded by the master layout when
layout_rtl is on. The remaining plugins referenced in config (Flatpickr, Tom
Select, Tabulator, Quill) are bundled/imported through your Vite pipeline rather
than copied here.
The app.js initializers
The published entry point resources/js/adminlte.js (from app.js.stub) imports
Bootstrap, OverlayScrollbars and admin-lte, then feature-detects the
globally-loaded plugin libraries and wires them up on DOM-ready. Because the
libraries are loaded as global <script> tags via @pluginScripts, each
initializer no-ops if its global is absent:
| Initializer | Trigger attribute | Notes |
|---|---|---|
initCharts() |
[data-apexchart] |
Reads data-apexchart-config (JSON), renders an ApexCharts instance. |
initVectorMaps() |
[data-jsvectormap] |
Requires an element id; reads data-jsvectormap-config. Warns if map data is missing. |
initCalendars() |
[data-fullcalendar] |
Reads data-fullcalendar-config; renders a FullCalendar. |
initSortables() |
[data-sortable] and [data-sortable-kanban] |
Generic lists read data-sortable-options; kanban lanes ([data-sortable-group]) share one group per board. |
Each initializer marks processed elements with a data-*Ready flag so they
aren't initialized twice. Invalid JSON in a config attribute is logged with a
warning and treated as an empty config.