Alright! Our application is starting to take shape, but let's be honest—it looks pretty basic right now. This is just the start of having our full Chirper application, but let's give it some TLC. We're going to add user avatars, format some timestamps, and use DaisyUI's components to make this look just a little bit nicer.
Let's transform this into something that actually looks like a social media feed!
The first thing I want to tackle is this home.blade.php file. It's great, but it'd be nice if we could get every chirp as its own component. That way we only have one place where we're modifying how chirps are displayed.
Blade components aren't just for layouts—they're perfect for reusable UI pieces like this! Let's create a component for displaying individual chirps:
Create a new file at resources/views/components/chirp.blade.php
:
1@props(['chirp']) 2 3<div class="card bg-base-100 shadow"> 4 <div class="card-body"> 5 <div class="flex space-x-3"> 6 @if($chirp->user) 7 <div class="avatar"> 8 <div class="size-10 rounded-full"> 9 <img src="<https://avatars.laravel.cloud/>{{ urlencode($chirp->user->email) }}"10 alt="{{ $chirp->user->name }}'s avatar"11 class="rounded-full" />12 </div>13 </div>14 @else15 <div class="avatar placeholder">16 <div class="size-10 rounded-full">17 <img src="<https://avatars.laravel.cloud/f61123d5-0b27-434c-a4ae-c653c7fc9ed6?vibe=stealth>"18 alt="Anonymous User"19 class="rounded-full" />20 </div>21 </div>22 @endif23 24 <div class="min-w-0">25 <div class="flex items-center gap-1">26 <span class="text-sm font-semibold">{{ $chirp->user ? $chirp->user->name : 'Anonymous' }}</span>27 <span class="text-base-content/60">·</span>28 <span class="text-sm text-base-content/60">{{ $chirp->created_at->diffForHumans() }}</span>29 </div>30 31 <p class="mt-1">32 {{ $chirp->message }}33 </p>34 </div>35 </div>36 </div>37</div>
Let me walk you through what we changed here. This is pretty close to what we had previously, but now we're just making it a little bit cleaner.
Notice a few key things:
Avatar magic: If there is a chirp user, we're using avatars.laravel.cloud
, which is a free service that generates these neat little gradients for you whenever you need avatars for your application. We're just passing in the user's email to generate them specifically for that user.
Anonymous fallback: We have a default avatar for anonymous users too.
Props power: Here's the neat thing about Blade components—we can pass in a prop (in this case, a chirp model instance). This prop then allows us to access $chirp->user
, $chirp->message
, $chirp->created_at
, and so on when we use this component in our views.
Note: We're handling both authenticated and anonymous chirps. In lesson 11, we'll add authentication so every chirp has a real user!
Now that we have our chirp component, let's update home.blade.php
to use it. We're still looping through all the chirps like we did before—we're just doing it with our new component instead.
1<x-layout> 2 <x-slot:title> 3 Home Feed 4 </x-slot:title> 5 6 <div class="max-w-2xl mx-auto"> 7 <h1 class="text-3xl font-bold mt-8">Latest Chirps</h1> 8 9 <div class="space-y-4 mt-8">10 @forelse ($chirps as $chirp)11 <x-chirp :chirp="$chirp" />12 @empty13 <div class="hero py-12">14 <div class="hero-content text-center">15 <div>16 <svg class="mx-auto h-12 w-12 opacity-30" fill="none" stroke="currentColor" viewBox="0 0 24 24">17 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"></path>18 </svg>19 <p class="mt-4 text-base-content/60">No chirps yet. Be the first to chirp!</p>20 </div>21 </div>22 </div>23 @endforelse24 </div>25 </div>26</x-layout>
Notice that we're passing in the :chirp
prop to our <x-chirp>
component—that colon indicates it's a prop we can pass into the component. Pretty neat, right?
Now that we're cruising along, why don't we get some more sample data without having to open php artisan tinker
every time we want to create chirps? Laravel gives us an easy way to do this with something called seeders.
Let's create a seeder to generate some sample chirps. Run:
1php artisan make:seeder ChirpSeeder
Now, let's edit database/seeders/ChirpSeeder.php
. Seeders are a great way to make sample data so we can make sure our application is looking and feeling and working the way we expect.
We won't get into factories in this particular course, but factories are a great way to make random data. Seeders, on the other hand, are going to be a little bit more specific—they're basically just telling our database to run particular commands. You can think of seeders as an automated way to run php artisan tinker
commands, so you don't have to type it all out.
1<?php 2 3namespace Database\Seeders; 4 5use App\Models\User; 6use App\Models\Chirp; 7use Illuminate\Database\Seeder; 8 9class ChirpSeeder extends Seeder10{11 public function run(): void12 {13 // Create a few sample users if they don't exist14 $users = User::count() < 315 ? collect([16 User::create([17 'name' => 'Alice Developer',19 'password' => bcrypt('password'),20 ]),21 User::create([22 'name' => 'Bob Builder',24 'password' => bcrypt('password'),25 ]),26 User::create([27 'name' => 'Charlie Coder',29 'password' => bcrypt('password'),30 ]),31 ])32 : User::take(3)->get();33 34 // Sample chirps35 $chirps = [36 'Just discovered Laravel - where has this been all my life? 🚀',37 'Building something cool with Chirper today!',38 'Laravel\'s Eloquent ORM is pure magic ✨',39 'Deployed my first app with Laravel Cloud. So smooth!',40 'Who else is loving Blade components?',41 'Friday deploys with Laravel? No problem! 😎',42 ];43 44 // Create chirps for random users45 foreach ($chirps as $message) {46 $users->random()->chirps()->create([47 'message' => $message,48 'created_at' => now()->subMinutes(rand(5, 1440)),49 ]);50 }51 }52}
These are just some sample chirps in an array, and we're saying if there are fewer than three users (which there currently are in the database), let's go ahead and create some new users with this information. Again, this is exactly what we would do within tinker—this is just making it a little bit easier for us.
For each chirp message, every user is going to get a random chirp based off of this chirps array. Pretty cool, right?
Now let's run the seeder:
1php artisan db:seed --class=ChirpSeeder
Running the seeder command is as simple as that! A database was successfully seeded.
Again, a seeder is just an easier way to have all those tinker commands run for us, but within a way that Laravel expects. In this case, we're just running all that PHP code, but seeding the database with it.
Your feed looks great, but I want to make you aware of something we're not going to touch in this course, but something you might want to look into in the future: keeping this form up to date in real-time.
Right now, you can see that when we post a chirp, it says "0 seconds ago." But if anyone else accesses this page, they won't see new chirps until they actually refresh the page. Laravel has some great options for this, such as WebSockets with something like Laravel Reverb, which can notify all users when a new chirp comes in.
Here's what Laravel offers for real-time features:
Laravel Broadcasting - Push updates to browsers in real-time
Laravel Echo - JavaScript library for receiving broadcasts
Pusher or Laravel Reverb - WebSocket servers for real-time communication
Again, not something we're going to be touching on in this course, but it's helpful to know that those options are out there and might be a great way to build on top of what we're building here with Chirper!
Look at that! Your feed now has:
A reusable Blade component for chirps
Beautiful user avatars generated specifically for each user based on their email
User information and formatted timestamps
A polished, professional design with DaisyUI
Handles empty states gracefully
A clean way of generating sample data with seeders
So we're really moving right along! We now have a reusable Blade component for chirps, a way to generate chirps if we ever need to reset the database and start it up again, and a clean way of showing user information.
But it's still read-only. Next up: since it's still read-only, we're going to let users create their own chirps. Time to make this social network actually social!
Laravel is the most productive way to
build, deploy, and monitor software.