Dashboards are the nerve center of modern applications. Whether you’re tracking user growth, revenue, or system metrics, a well‑designed dashboard provides clarity and insight. Laravel gives us the backend power, Chart.js provides sleek visualizations, and Vue.js adds reactivity and modularity. Together, they form a perfect stack for building dynamic dashboards.
🎯 Why This Stack?
- Laravel: Handles data aggregation, APIs, and authentication.
- Chart.js: Lightweight, responsive, and supports multiple chart types.
- Vue.js: Component‑based, reactive, and scales beautifully with complex dashboards.
🛠️ Step 1: Setting Up Laravel + Vue
- Create a fresh Laravel project:
composer create-project laravel/laravel laravel-dashboard cd laravel-dashboard php artisan serve - Install Vue:
npm install vue@next chart.js - Configure
resources/js/app.js:import { createApp } from 'vue';import UserChart from './components/UserChart.vue';import RevenueChart from './components/RevenueChart.vue';import CategoryChart from './components/CategoryChart.vue';const app = createApp({});app.component('user-chart', UserChart);app.component('revenue-chart', RevenueChart);app.component('category-chart', CategoryChart);app.mount('#app');
📊 Step 2: Backend Data Preparation
Example controller (DashboardController.php):
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Order;
class DashboardController extends Controller
{
public function index()
{
$usersPerMonth = User::selectRaw('MONTH(created_at) as month, COUNT(*) as count')
->groupBy('month')
->pluck('count', 'month');
$revenuePerMonth = Order::selectRaw('MONTH(created_at) as month, SUM(amount) as total')
->groupBy('month')
->pluck('total', 'month');
$categoryDistribution = Order::selectRaw('category, COUNT(*) as count')
->groupBy('category')
->pluck('count', 'category');
return view('dashboard', compact('usersPerMonth', 'revenuePerMonth', 'categoryDistribution'));
}
}
🎨 Step 3: Blade View with Vue Components
resources/views/dashboard.blade.php:
<!DOCTYPE html>
<html>
<head>
<title>Laravel Dashboard</title>
@vite('resources/js/app.js')
</head>
<body>
<div id="app">
<h1>Dashboard</h1>
<user-chart :chart-data='@json($usersPerMonth)'></user-chart>
<revenue-chart :chart-data='@json($revenuePerMonth)'></revenue-chart>
<category-chart :chart-data='@json($categoryDistribution)'></category-chart>
</div>
</body>
</html>
📈 Step 4: Multiple Chart Types with Vue Components
1. Line Chart (User Growth)
resources/js/components/UserChart.vue:
<template>
<canvas id="userChart"></canvas>
</template>
<script>
import { Chart } from 'chart.js/auto';
export default {
props: ['chartData'],
mounted() {
new Chart(document.getElementById('userChart'), {
type: 'line',
data: {
labels: Object.keys(this.chartData),
datasets: [{
label: 'Users Registered',
data: Object.values(this.chartData),
borderColor: '#42A5F5',
backgroundColor: 'rgba(66, 165, 245, 0.2)',
fill: true,
tension: 0.3
}]
}
});
}
}
</script>
2. Bar Chart (Revenue)
resources/js/components/RevenueChart.vue:
<template>
<canvas id="revenueChart"></canvas>
</template>
<script>
import { Chart } from 'chart.js/auto';
export default {
props: ['chartData'],
mounted() {
new Chart(document.getElementById('revenueChart'), {
type: 'bar',
data: {
labels: Object.keys(this.chartData),
datasets: [{
label: 'Revenue ($)',
data: Object.values(this.chartData),
backgroundColor: '#4CAF50'
}]
}
});
}
}
</script>
3. Pie Chart (Category Distribution)
resources/js/components/CategoryChart.vue:
<template>
<canvas id="categoryChart"></canvas>
</template>
<script>
import { Chart } from 'chart.js/auto';
export default {
props: ['chartData'],
mounted() {
new Chart(document.getElementById('categoryChart'), {
type: 'pie',
data: {
labels: Object.keys(this.chartData),
datasets: [{
label: 'Orders by Category',
data: Object.values(this.chartData),
backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56', '#4CAF50']
}]
}
});
}
}
</script>
4. Radar Chart (Performance Metrics)
Optional component for advanced dashboards:
<template>
<canvas id="performanceChart"></canvas>
</template>
<script>
import { Chart } from 'chart.js/auto';
export default {
props: ['chartData'],
mounted() {
new Chart(document.getElementById('performanceChart'), {
type: 'radar',
data: {
labels: Object.keys(this.chartData),
datasets: [{
label: 'Performance',
data: Object.values(this.chartData),
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: '#FF6384'
}]
}
});
}
}
</script>
🔧 Step 5: Dynamic API Integration
Instead of embedding data directly, fetch via API:
fetch('/api/revenue-per-month')
.then(res => res.json())
.then(data => {
chart.data.labels = Object.keys(data);
chart.data.datasets[0].data = Object.values(data);
chart.update();
});
🧭 Final Thoughts
By combining Laravel, Vue.js, and Chart.js, you can build dashboards that are:
- Reactive: Charts update instantly when data changes.
- Modular: Each chart is a Vue component.
- Versatile: Line, bar, pie, radar, and more.
- Scalable: Perfect for SaaS dashboards, admin panels, or analytics platforms.
This stack empowers developers to deliver dashboards that are not only functional but also visually compelling — turning raw data into actionable insights.
