Unlock Your Laravel App's Potential: Mastering Roles & Permissions with InertiaJS in Laravel 12

Author

Kritim Yantra

Jun 12, 2025

Unlock Your Laravel App's Potential: Mastering Roles & Permissions with InertiaJS in Laravel 12

Ever built a sleek Laravel app, only to realize different users need different access levels? Maybe admins should delete posts, editors can draft content, and regular users just view it? Roles and permissions are your solution—and combining them with Laravel 12 and InertiaJS makes implementation smoother than ever. Let’s build this together, step by step!


🔑 Why Bother with Roles & Permissions?

Imagine a library:

  • Librarians (admins) can add/remove books.
  • Members (users) can only borrow.
  • Guests can browse but not borrow.

Without clear rules, chaos reigns! In web apps, roles/permissions:

  • Protect sensitive data
  • Customize user experiences
  • Prevent accidental/malicious actions

🧰 What You’ll Need

  1. Laravel 12 installed (Official docs)
  2. InertiaJS configured with Vue or React
  3. Spatie’s Laravel-Permission package (industry standard)
  4. Basic Laravel & Vue/React knowledge

💡 Never worked with Inertia? Check Laravel’s Inertia starter kit first!


️ Step 1: Install Spatie’s Permission Package

Think of this like adding a security module to your app.
Run:

composer require spatie/laravel-permission

Publish configs/migrations:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

Migrate your database:

php artisan migrate

👮 Step 2: Define Roles & Permissions

Permissions = Actions (e.g., create-post, delete-user)
Roles = Job Titles (e.g., admin, editor)

Add this to DatabaseSeeder.php:

use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;

public function run() {
    // Create roles
    $admin = Role::create(['name' => 'admin']);
    $editor = Role::create(['name' => 'editor']);
    
    // Create permissions
    $createPost = Permission::create(['name' => 'create-post']);
    $deletePost = Permission::create(['name' => 'delete-post']);
    
    // Assign permissions to roles
    $admin->givePermissionTo([$createPost, $deletePost]);
    $editor->givePermissionTo($createPost);
}

Seed your database:

php artisan db:seed

🧑 Step 3: Assign Roles to Users

Give users their "job titles":

// When creating a user
$user = User::create([...]);
$user->assignRole('editor');

// Or later
$user = User::find(1);
$user->assignRole('admin');

Check permissions in controllers:

public function destroy(Post $post) {
    // Authorize on-the-fly
    $this->authorize('delete-post', $post); 
    
    // Or manually
    if (!auth()->user()->can('delete-post')) {
        abort(403, 'Access denied!');
    }
}

🛡️ Step 4: Protect Server-Side Routes

Lock sensitive routes like a vault:

// routes/web.php
Route::middleware(['auth', 'can:create-post'])->group(function () {
    Route::get('/posts/create', [PostController::class, 'create']);
});

Route::middleware(['auth', 'role:admin'])->group(function () {
    Route::delete('/users/{id}', [UserController::class, 'destroy']);
});

🖥️ Step 5: Sync Permissions to Inertia Frontend

Pass user permissions to Vue/React like a note:
Update app/Http/Middleware/HandleInertiaRequests.php:

public function share(Request $request): array {
    return array_merge(parent::share($request), [
        'auth' => [
            'user' => $request->user() 
                ? $request->user()->load('permissions') 
                : null
        ],
    ]);
}

Now access permissions in frontend via $page.props.auth.user.permissions!


🎨 Step 6: Dynamic UI in Vue/React Components

Show/hide buttons based on permissions:

<template>
  <!-- Hide delete button from non-admins -->
  <button 
    v-if="$page.props.auth.user?.can('delete-post')"
    @click="deletePost(post.id)"
    class="bg-red-500 text-white p-2"
  >
    Delete Post
  </button>

  <!-- Show admin dashboard link only to admins -->
  <NavLink 
    v-if="$page.props.auth.user?.hasRole('admin')" 
    href="/admin-dashboard"
  >
    Admin Panel
  </NavLink>
</template>

Create helper methods in resources/js/app.js:

// For Vue
app.config.globalProperties.$can = (permission) => {
    return Inertia.page.props.auth.user?.permissions?.includes(permission);
}

// Use like: v-if="$can('edit-post')"

🔐 Step 7: Frontend Route Protection (Optional)

Prevent unauthorized page access:

// In Vue/React page components
import { usePage } from '@inertiajs/vue3'

export default {
    mounted() {
        if (!this.$page.props.auth.user?.hasRole('admin')) {
            // Redirect non-admins
            this.$inertia.visit('/dashboard');
        }
    }
}

🎯 Key Takeaways

  1. Spatie’s package handles heavy permission lifting
  2. Always authorize server-side – client checks are for UX only!
  3. Load permissions via Inertia middleware to hydrate frontend
  4. Use v-if/hasRole() for dynamic UI rendering
  5. Permissions > Roles for granular control

🚨 Golden Rule: Server-side validation is NON-NEGOTIABLE for security. Frontend checks are just for usability!


🚀 Your Next Steps

  1. Explore Spatie’s permission docs
  2. Implement permission groups (e.g., post.edit, user.delete)
  3. Add a role management UI (assign roles in your app!)

You’ve just built a foundational security layer! Whether you’re creating a blog or enterprise SaaS, roles/permissions + Laravel 12 + InertiaJS is a game-changer. Questions? Share them below! 👇

LIVE MENTORSHIP ONLY 5 SPOTS

Laravel Mastery
Coaching Class Program

KritiMyantra

Transform from beginner to Laravel expert with our personalized Coaching Class starting June 20, 2025. Limited enrollment ensures focused attention.

Daily Sessions

1-hour personalized coaching

Real Projects

Build portfolio applications

Best Practices

Industry-standard techniques

Career Support

Interview prep & job guidance

Total Investment
$200
Duration
30 hours
1h/day

Enrollment Closes In

Days
Hours
Minutes
Seconds
Spots Available 5 of 10 remaining
Next cohort starts:
June 20, 2025

Join the Program

Complete your application to secure your spot

Application Submitted!

Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.

What happens next?

  • Confirmation email with program details
  • WhatsApp message from our team
  • Onboarding call to discuss your goals

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts