Skip to content

Vue SPA using PrimeVue components, meant to use with Laravel Breeze API stack on the backend.

Notifications You must be signed in to change notification settings

connorabbas/laravel-api-primevue-starter-kit

Repository files navigation

PrimeVue SPA & Laravel API Starter Kit

Static Badge Static Badge Static Badge

A PrimeVue SPA starter kit meant for use with a Laravel Breeze API stack backend.

An alternative to using the Laravel & PrimeVue (Inertia.js) Starter Kit.

Setup

  1. Clone the repo (or download the zip)

  2. Create a new .env file in the root directory, reference the .env.example file for the vars/values

  3. Create a new Laravel application

  4. Install Laravel Breeze using the API Stack option

  5. Setup necessary .env configuration values in the Laravel API project

    # Example implementation
    # Remember, your SPA and API must share the same top-level domain
    APP_URL=http://api.vue-spa.localhost # Match this value with VITE_API_BASE_URL in the Vue app
    FRONTEND_URL=http://vue-spa.localhost # Add app.frontend_url config entry as needed
    SANCTUM_STATEFUL_DOMAINS="vue-spa.localhost"
    SESSION_DOMAIN="vue-spa.localhost"
    
  6. Setup additional routes and controllers for profile settings in the Laravel API project:

    php artisan make:controller ProfileController
    
    <?php
    
    namespace App\Http\Controllers;
    
    use App\Models\User;
    use Illuminate\Http\Request;
    use Illuminate\Http\Response;
    use Illuminate\Support\Facades\Auth;
    use Illuminate\Validation\Rule;
    use Illuminate\View\View;
    
    class ProfileController extends Controller
    {
        /**
        * Update the user's profile information.
        */
        public function update(Request $request): Response
        {
            $validated = $request->validate([
                'name' => ['required', 'string', 'max:255'],
                'email' => [
                    'required',
                    'string',
                    'lowercase',
                    'email',
                    'max:255',
                    Rule::unique(User::class)->ignore($request->user()->id),
                ],
            ]);
    
            $request->user()->fill($validated);
    
            if ($request->user()->isDirty('email')) {
                $request->user()->email_verified_at = null;
            }
    
            $request->user()->save();
    
            return response()->noContent();
        }
    
        /**
        * Delete the user's account.
        */
        public function destroy(Request $request): Response
        {
            $request->validate([
                'password' => ['required', 'current_password'],
            ]);
    
            $user = $request->user();
    
            Auth::logout();
    
            $user->delete();
    
            $request->session()->invalidate();
            $request->session()->regenerateToken();
    
            return response()->noContent();
        }
    }
    php artisan make:controller Auth/PasswordController
    
    <?php
    
    namespace App\Http\Controllers\Auth;
    
    use App\Http\Controllers\Controller;
    use Illuminate\Http\Request;
    use Illuminate\Http\Response;
    use Illuminate\Support\Facades\Auth;
    use Illuminate\Support\Facades\Hash;
    use Illuminate\Validation\Rules\Password;
    
    class PasswordController extends Controller
    {
        /**
        * Update the user's password.
        */
        public function update(Request $request): Response
        {
            $validated = $request->validate([
                'current_password' => ['required', 'current_password'],
                'password' => ['required', Password::defaults(), 'confirmed'],
            ]);
    
            $request->user()->update([
                'password' => Hash::make($validated['password']),
            ]);
    
            if ($request->session()->has('password_hash_web')) {
                $user = Auth::user();
                $request->session()->forget('password_hash_web');
                Auth::login($user);
            }
    
            return response()->noContent();
        }
    }
    Route::controller(App\Http\Controllers\ProfileController::class)
        ->middleware('auth')
        ->group(function () {
            Route::patch('/profile', 'update')->name('profile.update');
            Route::delete('/profile', 'destroy')->name('profile.destroy');
        });
    
    Route::put('password', [App\Http\Controllers\Auth\PasswordController::class, 'update'])
        ->middleware('auth')
        ->name('password.update');

TypeScript

TypeScript is configured and ready for use if desired, but is not required.

Theme

This starter kit provides a collection of custom theme presets to choose from, built using the powerful PrimeVue V4 theming system. It leverages styled mode and custom design token values to create flexible and cohesive UI designs.

Provided Theme Presets

The theme presets are located in the /resources/js/theme directory. Each preset offers a distinct visual style:

  • bootstrap
    Emulates the look and feel of Bootstrap.

  • breeze
    Captures the aesthetic of Laravel Breeze. (R.I.P. 🙏)

  • enterprise
    Provides a clean, no-nonsense corporate design.

  • noir
    A minimal & clean monochromatic style that serves as the default theme.

  • warm
    A boxy design with a warmer color pallette.

Customizing Your Own Theme

Creating your own theme preset is simple. You can:

For detailed guidance on customization, please refer to the PrimeVue Styled Mode Docs.

PrimeVue v4 w/ Tailwind CSS

To clarify, Tailwind is not used for any component styling in this starter kit; instead, we use PrimeVue's styled mode with a custom theme preset implementation for component styling. Tailwind is applied solely for layout purposes around PrimeVue components and for minimal styling when needed.

About

Vue SPA using PrimeVue components, meant to use with Laravel Breeze API stack on the backend.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published