{"id":261,"date":"2025-08-27T16:40:24","date_gmt":"2025-08-27T16:40:24","guid":{"rendered":"https:\/\/1v0.net\/blog\/?p=261"},"modified":"2025-08-27T16:40:25","modified_gmt":"2025-08-27T16:40:25","slug":"creating-a-role-specific-dashboard-in-laravel-12","status":"publish","type":"post","link":"https:\/\/1v0.net\/blog\/creating-a-role-specific-dashboard-in-laravel-12\/","title":{"rendered":"Creating a Role-Specific Dashboard in Laravel 12"},"content":{"rendered":"\n<p>In many applications, different users need different dashboards. For example, an <strong>admin<\/strong> might see system statistics, a <strong>manager<\/strong> might see team performance, while a <strong>user<\/strong> only sees their own activity. In <strong>Laravel 12<\/strong>, you can create <strong>role-specific dashboards<\/strong> using the Spatie Permissions package and some conditional logic.<\/p>\n\n\n\n<p>In this guide, we\u2019ll build dashboards that automatically adapt based on the logged-in user\u2019s role. We\u2019ll secure routes, load different views, and provide a clean UI for each role.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>1 &#8211; Defining Roles<\/strong><\/h2>\n\n\n\n<p>Before building dashboards, make sure your roles are defined with <a href=\"\/blog\/laravel-spatie-permissions-step-by-step-installation-setup\">Spatie Permissions<\/a>. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">php<\/span> <span class=\"hljs-selector-tag\">artisan<\/span> <span class=\"hljs-selector-tag\">tinker<\/span>\n\n&gt;&gt;&gt; <span class=\"hljs-selector-tag\">Role<\/span><span class=\"hljs-selector-pseudo\">::create(<\/span><span class=\"hljs-selector-attr\">&#91;<span class=\"hljs-string\">'name'<\/span> =&gt; <span class=\"hljs-string\">'admin'<\/span>]<\/span>);\n&gt;&gt;&gt; <span class=\"hljs-selector-tag\">Role<\/span><span class=\"hljs-selector-pseudo\">::create(<\/span><span class=\"hljs-selector-attr\">&#91;<span class=\"hljs-string\">'name'<\/span> =&gt; <span class=\"hljs-string\">'manager'<\/span>]<\/span>);\n&gt;&gt;&gt; <span class=\"hljs-selector-tag\">Role<\/span><span class=\"hljs-selector-pseudo\">::create(<\/span><span class=\"hljs-selector-attr\">&#91;<span class=\"hljs-string\">'name'<\/span> =&gt; <span class=\"hljs-string\">'user'<\/span>]<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Assign roles to users when registering or via an admin UI. Example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$user-&gt;assignRole(<span class=\"hljs-string\">'admin'<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>2 &#8211; Route Setup<\/strong><\/h2>\n\n\n\n<p>We\u2019ll use a single dashboard route that points to a controller. Middleware ensures only authenticated users can access it.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ routes\/web.php<\/span>\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Controllers<\/span>\\<span class=\"hljs-title\">DashboardController<\/span>;\n\nRoute::middleware(&#91;<span class=\"hljs-string\">'auth'<\/span>])-&gt;get(<span class=\"hljs-string\">'\/dashboard'<\/span>, &#91;DashboardController::class, <span class=\"hljs-string\">'index'<\/span>])-&gt;name(<span class=\"hljs-string\">'dashboard'<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>3 &#8211; Dashboard Controller<\/strong><\/h2>\n\n\n\n<p>The controller checks the user\u2019s role and returns the correct view. This keeps logic centralized.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ app\/Http\/Controllers\/DashboardController.php<\/span>\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Controllers<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Support<\/span>\\<span class=\"hljs-title\">Facades<\/span>\\<span class=\"hljs-title\">Auth<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">DashboardController<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Controller<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">index<\/span><span class=\"hljs-params\">()<\/span>\n    <\/span>{\n        $user = Auth::user();\n\n        <span class=\"hljs-keyword\">if<\/span> ($user-&gt;hasRole(<span class=\"hljs-string\">'admin'<\/span>)) {\n            <span class=\"hljs-keyword\">return<\/span> view(<span class=\"hljs-string\">'dashboards.admin'<\/span>);\n        }\n\n        <span class=\"hljs-keyword\">if<\/span> ($user-&gt;hasRole(<span class=\"hljs-string\">'manager'<\/span>)) {\n            <span class=\"hljs-keyword\">return<\/span> view(<span class=\"hljs-string\">'dashboards.manager'<\/span>);\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> view(<span class=\"hljs-string\">'dashboards.user'<\/span>);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now, each role gets its own dashboard view file.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>4 &#8211; Creating Dashboard Views<\/strong><\/h2>\n\n\n\n<p>Let\u2019s create separate views for each role:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">\/\/ resources\/views\/dashboards\/admin.blade.php\n@extends('layouts.app')\n\n@section('content')\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Admin Dashboard<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>System statistics and user management tools go here.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n@endsection<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">\/\/ resources\/views\/dashboards\/manager.blade.php\n@extends('layouts.app')\n\n@section('content')\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Manager Dashboard<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Team performance metrics and project controls go here.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n@endsection<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">\/\/ resources\/views\/dashboards\/user.blade.php\n@extends('layouts.app')\n\n@section('content')\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>User Dashboard<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Your personal activity, notifications, and profile tools go here.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n@endsection<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Each dashboard is independent, so you can customize the content for the needs of each role.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>5 &#8211; Securing Role-Specific Pages<\/strong><\/h2>\n\n\n\n<p>Sometimes you\u2019ll want to restrict not just dashboards but also subpages. You can use middleware or Blade directives for this.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ Example: restrict reports route to managers<\/span>\nRoute::middleware(&#91;<span class=\"hljs-string\">'auth'<\/span>,<span class=\"hljs-string\">'role:manager'<\/span>])-&gt;get(<span class=\"hljs-string\">'\/reports'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">'Reports Page'<\/span>;\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">\/\/ Example in Blade\n@role('admin')\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"\/admin\/settings\"<\/span>&gt;<\/span>Settings<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n@endrole<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This ensures that only users with the correct roles see links and access routes.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>We created a <strong>role-specific dashboard system in Laravel 12<\/strong>. Each user sees a different dashboard based on their role, managed with Spatie Permissions. Routes are protected with middleware, and Blade directives ensure the right UI is displayed. This approach provides a tailored experience for each type of user while keeping security intact.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">What\u2019s Next<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/blog\/building-a-team-management-system-with-laravel-roles-and-permissions\">Building a Team Management System with Laravel Roles &amp; Permissions<\/a><\/li>\n<li><a href=\"\/blog\/how-to-give-and-revoke-permissions-to-users-in-laravel\">How to Give and Revoke Permissions to Users in Laravel<\/a><\/li>\n<li><a href=\"\/blog\/laravel-roles-vs-policies-which-one-should-you-use\">Laravel Roles vs Policies: Which One Should You Use?<\/a><\/li>\n<\/ul>\n\n","protected":false},"excerpt":{"rendered":"<p>In many applications, different users need different dashboards. For example, an admin might see system statistics, a manager might see team performance, while a user only sees their own activity. In Laravel 12, you can create role-specific dashboards using the Spatie Permissions package and some conditional logic. In this guide, we\u2019ll build dashboards that automatically [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":265,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[23,35,15,17],"class_list":["post-261","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel","tag-access-control","tag-dashboard","tag-roles","tag-roles-and-permissions"],"_links":{"self":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/comments?post=261"}],"version-history":[{"count":1,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/261\/revisions"}],"predecessor-version":[{"id":264,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/261\/revisions\/264"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media\/265"}],"wp:attachment":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media?parent=261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/categories?post=261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/tags?post=261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}