Charts & Plugins
Charts, calendars, maps and rich inputs are powered by optional JavaScript libraries that AdminLTE 4 for Laravel lazy-loads. A plugin's assets are only emitted on pages that actually use it, keeping the base layout lean — managed by the PluginManager singleton and the @pluginStyles / @pluginScripts Blade directives.
Components auto-enable their plugin
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 wiring required:
| Component | Plugin enabled |
|---|---|
<x-adminlte-chart> | chartjs |
<x-adminlte-vector-map> | jsvectormap |
<x-adminlte-calendar> | fullcalendar |
<x-adminlte-kanban> / <x-adminlte-sortable> | sortablejs |
<x-adminlte-input-flatpickr> | flatpickr |
<x-adminlte-input-tom-select> | tom_select |
<x-adminlte-datatable> | tabulator |
<x-adminlte-editor> | quill |
A chart in two lines
<x-adminlte-chart type="bar"
:series="[['name' => 'Sales', 'data' => [30, 40, 35, 50]]]"
:categories="['Q1', 'Q2', 'Q3', 'Q4']" height="320px" />
<x-adminlte-calendar :events="[
['title' => 'Launch', 'start' => '2026-06-01'],
]" height="600px" />
<x-adminlte-vector-map map="world_merc"
:markers="[['name' => 'London', 'coords' => [51.5, -0.12]]]" height="450px" />
Each component serializes its config to a data-*-config attribute; the published resources/js/adminlte.js feature-detects the global library and initializes matching elements on DOM-ready (maps via [data-jsvectormap], calendars via [data-fullcalendar], etc.). Charts are rendered by the Chart.js preset instead — see below.
Charts (Chart.js)
Charts use Chart.js 4 (MIT). <x-adminlte-chart> keeps its props — type, series, categories, options, id, height — and turns them into a Chart.js config:
type:area(the default, a filled line),line,bar,pie,donut,radar,polarArea,scatter,bubbleorsparkline.series: a list of['name' => …, 'data' => […]](plus any Chart.js dataset keys), or a flat list of numbers for pie/donut slices.categoriesare the labels.options: Chart.js options (plugins,scales,indexAxis, …), deep-merged over the defaults. A few old ApexCharts keys (colors,chart.stacked,plotOptions.bar.horizontal,legend.show,xaxis.categories,yaxis.min/max, …) are still translated; other ApexCharts keys are dropped.idis the<canvas>id, soChart.getChart('sales')returns the chart.
<x-adminlte-chart id="sales" type="bar"
:series="[['name' => 'Sales', 'data' => [30, 40, 35, 50]], ['name' => 'Returns', 'data' => [3, 5, 2, 4]]]"
:categories="['Q1', 'Q2', 'Q3', 'Q4']"
:options="['indexAxis' => 'y', 'scales' => ['x' => ['stacked' => true], 'y' => ['stacked' => true]]]"
height="320px" />
Theme preset and dark mode
The chartjs plugin loads two files: vendor/chartjs/chart.umd.min.js and the preset this package ships, vendor/adminlte/js/charts.js (both copied by adminlte:install). The preset sets Chart.defaults from the page's CSS variables (--bs-body-font-family, --bs-secondary-color, --bs-border-color-translucent, …), re-themes every chart when the light/dark/auto toggle changes data-bs-theme or the text direction flips, renders every <x-adminlte-chart> (canvas[data-adminlte-chart]), and resizes charts when a tab, modal, collapse or card is shown. Series without their own colours take the theme palette (--bs-primary, --bs-teal, …); a colour written as 'var(--bs-success)' is re-read on every update, so it follows dark mode and primary_color.
For charts you write by hand, enable the plugin and use the window.AdminLteCharts helpers (create, sparkline, color, alpha, palette, refresh, init):
@php app(\ColorlibHQ\AdminLte\Plugins\PluginManager::class)->enable('chartjs'); @endphp
<div id="revenue" style="height: 300px"></div>
<div id="spark" style="width: 120px; height: 30px"></div>
@push('js')
<script>
document.addEventListener('DOMContentLoaded', () => {
AdminLteCharts.create('#revenue', {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar'],
datasets: [{ label: 'Revenue', data: [12, 19, 15], borderColor: 'var(--bs-primary)', fill: 'origin' }],
},
})
AdminLteCharts.sparkline('#spark', [5, 9, 7, 12], { color: 'var(--bs-success)', tooltip: true })
})
</script>
@endpush
Chart is a global, so new Chart(canvas, config) and Chart.register(plugin) for Chart.js plugins work too; those charts pick up the theme defaults and live re-theming for colours they don't set. Callbacks (tooltip or tick formatters) can be added to a component chart through Chart.getChart(id).
The plugins config
Each plugin is defined under the plugins key in config/adminlte.php, with enabled, an optional css, and a js path (string or array). Paths resolve via asset(), relative to public/:
'plugins' => [
'chartjs' => [
'enabled' => false,
'js' => [
'vendor/chartjs/chart.umd.min.js',
'vendor/adminlte/js/charts.js', // the AdminLTE preset, after Chart.js
],
],
'jsvectormap' => [
'enabled' => false,
'css' => 'vendor/jsvectormap/jsvectormap.min.css',
'js' => [
'vendor/jsvectormap/jsvectormap.min.js',
'vendor/jsvectormap/maps/world.js', // loads the 'world' map
],
],
],
Set enabled => true to load a plugin on every page; otherwise it loads only when a component turns it on. Drive it manually from a view if needed:
@php app(\ColorlibHQ\AdminLte\Plugins\PluginManager::class)->enable('chartjs'); @endphp
Vendor files
php artisan adminlte:install copies the JS-only plugins (Chart.js, jsVectorMap, FullCalendar, SortableJS), the AdminLTE RTL stylesheet and the chart preset (vendor/adminlte/js/charts.js) into public/vendor/. The remaining plugins (Flatpickr, Tom Select, Tabulator, Quill) are bundled through Vite and are disabled by default — install them only when you enable them:
npm install -D flatpickr@^4.6 tom-select@^2.4 tabulator-tables@^6.0 quill@^2.0
Upgrading from an ApexCharts release: the apexcharts plugin key is replaced by chartjs (registered even if your published config/adminlte.php has no entry for it). Run npm install -D chart.js@^4.5 and php artisan adminlte:install --only=assets, then re-publish or delete any views you published earlier, since those still call ApexCharts.
The master layout emits @pluginStyles in <head> and @pluginScripts at the bottom of <body> at request time, so a plugin enabled by a component earlier in the same request is always included. Order is preserved (e.g. jsVectorMap loads the library before the world-map data).