Building Chirper with Laravel Breeze Intertia and Vue

Step 1: Installing Laravel and Breeze

  1. Install Laravel by running the following command in your terminal:
  2. composer create-project --prefer-dist laravel/laravel laravelvue
  3. Create a blank repository in GitHub called “laravue” and push the code running the following command in your terminal:
  4. 
          git init
          git branch -M main
          git remote add origin https://github.com/dipankar77/laravue.git
          git add .
          git commit -m "first commit"
          git push -u origin main
        
  5. Install Laravel Breeze and Vue by running the following command in your terminal:
  6.     
         composer require laravel/breeze --dev
         php artisan breeze:install vue
        
       
  7. Start the Laravel development server by running the following command:
  8. php artisan serve
  9. Start the Vite development server by running the following command:
  10. npm run dev
  11. Run the migration to create default tables from Laravel and Breeze tables in your database:
  12. php artisan migrate

Step 2: Creating Chirps

  1. create a model, migration, and resource controller for our Chirps with the following command:
  2. php artisan make:model -mrc Chirp

    This command will create three files for you:
    app/Models/Chirp.php – The Eloquent model.
    database/migrations/_create_chirps_table.php – The database migration that will create your database table.
    app/Http/Controllers/ChirpController.php – The HTTP controller that will take incoming requests and return responses.

  3. In routes/web.php create the following routes:
  4. <?php
    + use App\Http\Controllers\ChirpController;
      use Illuminate\Foundation\Application;
      use Illuminate\Support\Facades\Route;
      use Inertia\Inertia;
     ...
    Route::get('/dashboard', function () {
        return Inertia::render('Dashboard');
    })->middleware(['auth', 'verified'])->name('dashboard');
     
    Route::middleware('auth')->group(function () {
        Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
        Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
        Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
    +   Route::resource('chirps', ChirpController::class)
    +   ->only(['index', 'store']);
    });
     
    require __DIR__.'/auth.php';
      
  5. In app/Http/Controllers/ChirpController.php add the following codes to test it:
  6. <?php
    +use Illuminate\Http\Response; 
     
    class ChirpController extends Controller
    {
        /**
         * Display a listing of the resource.
         */
    -    public function index()
    +    public function index(): Response 
        {
            //
            return response('Hello, World!');
        }
     ...
    }
      
  7. Let’s update the index method of our ChirpController class app/Http/Controllers/ChirpController.php to render a front-end page component using Inertia.
  8. <?php
    namespace App\Http\Controllers;
     
    use App\Models\Chirp;
    use Illuminate\Http\Request;
    use Illuminate\Http\Response;
    use Inertia\Inertia;
    use Inertia\Response;
     
    class ChirpController extends Controller
    {
        /**
         * Display a listing of the resource.
         */
        public function index(): Response
        {
            return 'Hello, World!';
            return Inertia::render('Chirps/Index', [
                //
            ]);
        }
     ...
    }
      
  9. create our front-end Chirps/Index page at resources/js/Pages/Chirps/Index.vue component with a form for creating new Chirps:
  10. 
    
    <script>
    import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
    import InputError from '@/Components/InputError.vue';
    import PrimaryButton from '@/Components/PrimaryButton.vue';
    import { useForm, Head } from '@inertiajs/vue3';
     
    const form = useForm({
        message: '',
    });
    </script>
    
    <template>
        <Head title="Chirps" />
     
        <AuthenticatedLayout>
            <div class="max-w-2xl mx-auto p-4 sm:p-6 lg:p-8">
                <form @submit.prevent="form.post(route('chirps.store'), { onSuccess: () => form.reset() })">
                    <textarea
                        v-model="form.message"
                        placeholder="What's on your mind?"
                        class="block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm"
                    ></textarea>
                    <InputError :message="form.errors.message" class="mt-2" />
                    <PrimaryButton class="mt-4">Chirp</PrimaryButton>
                </form>
            </div>
        </AuthenticatedLayout>
    </template>
    
    
  11. Add a link to the navigation menu provided by Breeze at resources/js/Layouts/AuthenticatedLayout.vue
  12. 
    <div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
        <NavLink :href="route('dashboard')" :active="route().current('dashboard')">
            Dashboard
        </NavLink>
        <NavLink :href="route('chirps.index')" :active="route().current('chirps.index')">
            Chirps
        </NavLink>
    </div>
    
  13. And also for mobile screens:
  14. 
    <div class="pt-2 pb-3 space-y-1">
        <ResponsiveNavLink :href="route('dashboard')" :active="route().current('dashboard')">
            Dashboard
        </ResponsiveNavLink>
        <ResponsiveNavLink :href="route('chirps.index')" :active="route().current('chirps.index')">
            Chirps
        </ResponsiveNavLink>
    </div>
    
  15. Update the store method on our ChirpController class to validate the data and create a new Chirp:
  16. 
    <?php
    namespace App\Http\Controllers;
     
    use App\Models\Chirp;
    use Illuminate\Http\RedirectResponse;
    use Illuminate\Http\Request;
    use Inertia\Inertia;
    use Inertia\Response;
     
    class ChirpController extends Controller
    {
     ...
        /**
         * Store a newly created resource in storage.
         */
        public function store(Request $request)
        public function store(Request $request): RedirectResponse
        {
            //
            $validated = $request->validate([
                'message' => 'required|string|max:255',
            ]);
     
            $request->user()->chirps()->create($validated);
     
            return redirect(route('chirps.index'));
        }
     ...
    }
    
  17. We need to create this method on our User model to define a “has many” relationship:
  18. 
    <?php
    use Illuminate\Database\Eloquent\Relations\HasMany;
    use Illuminate\Foundation\Auth\User as Authenticatable;
    use Illuminate\Notifications\Notifiable;
    use Laravel\Sanctum\HasApiTokens;
     
    class User extends Authenticatable
    {
     ...
        public function chirps(): HasMany
        {
            return $this->hasMany(Chirp::class);
        }
    }
    
  19. add the $fillable property to our Chirp model to enable mass-assignment for the message attribute:
  20. 
    <?php
     ...
    class Chirp extends Model
    {
     ...
        protected $fillable = [
            'message',
        ];
    }
    
  21. add extra columns in our database to store the relationship between a Chirp and its User and the message itself.
  22. 
    <?php
     ...
    return new class extends Migration
    {
        /**
         * Run the migrations.
         */
        public function up(): void
        {
            Schema::create('chirps', function (Blueprint $table) {
                $table->id();
                $table->foreignId('user_id')->constrained()->cascadeOnDelete();
                $table->string('message');
                $table->timestamps();
            });
        }
     ...
    };
    
  23. We haven’t migrated the database since we added this migration, so let do it now:
  24. 
    php artisan migrate
    

Step 3: Showing Chirps

  • Update the index method our ChirpController class to pass Chirps from every user to our Index page:
  • 
    <?php
    class ChirpController extends Controller
    {
        /**
         * Display a listing of the resource.
         */
        public function index(): Response
        {
            return Inertia::render('Chirps/Index', [
                //
                'chirps' => Chirp::with('user:id,name')->latest()->get(),
            ]);
        }
     ...
    

    Leave A Comment