Our Chirper application is showing chirps that we have stored in the database, but we still don't have a way for our users to actually create their own chirps and store them in the database. A social network where you can only read? That's just a newspaper!
So that's what we're going to do in this lesson. We're going to build a form, handle the validation with that form, and store those chirps that users create in the database—all with the things that are built into Laravel. We're still saving the actual user authentication for a later lesson, but we are going to allow our users as anonymous users to create those chirps.
Step 1: Add a Create Form
Why don't we add the form at the top of our feed and we can get going from there. We really just want a form right after the "Latest Chirps" header, and before we actually list the chirps.
Let's update home.blade.php:
</x-layout>
There's nothing too special about this form right now—just one textarea and a button. But notice a couple of important things:
@csrf- Laravel's CSRF protection (prevents cross-site request forgery)POST to
/chirpsroute (which we'll create next)
If you tried to submit this form right now, nothing would actually happen because we haven't hooked it up on the Laravel side yet.
Step 2: Add the Store Route
So let's hook this up! In routes/web.php, add a route to handle form submission:
Step 3: Create the Store Method
First, I want to create the method that we're going to be submitting this form to in our controller. Let's go to our ChirpController and add the store method. This store method is perfect for this because we're creating a resource (in this case, a chirp), and this is what the store method is intended for in a resource controller.
}
Let me break this down:
Validation: We're validating the request and storing it in the
$validatedparameter. We're saying the message that we're receiving from this request is required, should be a string, and have a max of 255 characters. Notice we now have two places where this max is indicated—our validation as well as in the database itself.Creation: We're using the Chirp model to create this with a message from the validated data and a user_id of null (for now).
Redirect: We're returning a redirect back to the homepage with a specific success message. In Laravel, this
withfunction returns with a flash of data to the session—so after we redirect back, that initial load flashes a piece of data to the session with this success message.
Note: We're creating chirps without a user for now to keep things simple. In lesson 11, we'll add proper authentication so each chirp belongs to the logged-in user!
Step 4: Show Success Messages
Now, how can we grab this flash session information and display it to our user? In our app.css, we added that animate-fade-out parameter earlier—this is going to make things a lot easier when we create a notification component for any success messages.
We're not going to put this success message in our home.blade.php. Instead, we're going to put it in the layout so it can be used everywhere. Add this to your layout component (resources/views/components/layout.blade.php) right after the </nav>:
In this case, if the session has a parameter of 'success', we're going to show a toast. The toast is using DaisyUI classes, but we also have that animate-fade-out class that we added to our app.css. This is saying we're just going to take that session value, the success message, regardless of if this is from posting a chirp or if we use this for logging in and registering later.
The toast will appear at the top center and automatically fade away after a few seconds!
Step 5: Display Validation Errors
Now let's test this out! But first, what if someone tries to submit an empty chirp? We have client-side validation with that required attribute, but we also have server-side validation in our chirp controller. Let's make sure we can show validation errors properly.
Laravel gives us an errors variable that gets passed to the view if there are any errors within the session. Let's update the form section in home.blade.php to handle this:
</div>
Notice a few things here:
If there is an error with the message parameter (that's what we're validating in the controller), we add the
textarea-errorclassWe use
@error('message')to show the error messageDaisyUI gives us the ability to have the textarea show as an error state with that CSS class
We use
{{ old('message') }}so when we flash back after an error, the textarea displays the old input so the user doesn't have to retype everything
Laravel's validation automatically:
Redirects back on error
Provides error messages via
@errorPreserves old input with
old('message')
Step 6: Better Validation Messages
Now, to add just a little bit of UI nicety, let's customize our validation messages to be more "chirpy" and user-friendly. To show off the power of Laravel, we can actually customize these validation messages easily:
}
Now all of a sudden, within a couple of seconds, because of what Laravel gives to us, we have the ability to modify something as simple as error messages without having to do hardly anything!
Step 7: Test It Out!
Let's test our form:
Try submitting an empty form - You'll see our custom validation error: "Please write something to chirp!"
Type more than 255 characters - The client-side
maxlengthattribute prevents it, but if someone bypassed that, our server-side validation would catch it with "Chirps must be 255 characters or less."Submit a valid chirp - You'll see the success message and your new chirp at the top of the feed!
Because we are redirecting, we automatically receive that new chirp because the / route is automatically getting all of the latest chirps and pushing them into our view.
Security Features We Get for Free
Laravel automatically protects you from:
CSRF attacks - That
@csrftoken ensures forms come from your siteSQL injection - Eloquent parameterizes all queries
Mass assignment - Only fields in
$fillablecan be setXSS attacks - Blade
{{ }}automatically escapes output
What About Rate Limiting?
Now, it is helpful to know that while we won't touch on it in this particular course, there's so much more that you could add here. What if you don't want your users to post five times within a second, or maybe a hundred times within a second? There are some bad eggs out there—really, you can't trust anyone on the web.
Well, Laravel has the ability to rate limit. What that means is that you can, within a matter of minutes, say "Hey, this particular chirp method can only be done by a user maybe one time every 60 seconds."
You could also prevent duplicate chirps if you wanted:
This would ensure each user's chirps are unique. But before we get into something like that...
What We've Accomplished
Look at what we've built! Your app can now:
Accept user input through a beautiful form
Validate that input on both client and server side
Store chirps in the database
Show custom success and error messages with nice toasts
Protect against common security threats automatically
Redirect users back with flash messages
We have this form and it works! We're submitting anonymous data for now, but the validation works perfectly. Laravel automatically gives us both client-side validation and server-side validation.
But users can only create chirps—they can't edit or delete them yet. In the next lesson, we'll start working on editing and deleting chirps, even before we get to the user authentication piece. Let's check out how you can edit and delete chirps!