Laravel 12 - Honeypot (Spam Protection)

Touseef Afridi
12 Jul 25

Laravel 12 - Honeypot (Spam Protection)

In this tutorial, we will learn how to add spam protection in Laravel 12 using Honeypot, a simple and effective method to block bots without disrupting user experience.


If you're a video person, feel free to skip the post and check out the video instead!


ï»żQuick Overview

This guide walks you through implementing honeypot protection in a Laravel 12 application. We begin by setting up a new Laravel project and installing the Spatie Honeypot package to guard against spam submissions. After adjusting the package configuration and enabling the honeypot field, we move on to building a simple contact form and integrating honeypot protection using the Blade directive. Next, we define the necessary routes to display the form and handle user input, applying honeypot middleware to filter out automated bot traffic. To wrap things up, we simulate a spam attempt to verify everything is working as expected, including custom responses for flagged submissions. This tutorial offers a clean and effective method for adding spam protection to your Laravel 12 forms.

Step # 1 : Set Up the Laravel Project.

If you don’t have Laravel installed globally, I recommend installing it first. It makes creating new projects much simpler. To install Laravel globally, run the following command.
composer global require laravel/installer
If you already have it installed, feel free to skip this step. Once Laravel is set up, create a new project by running.
laravel new honeypot
During the setup, choose the following options to match our stack.
  • Select None for the Starter Kit.
  • Choose Pest as the testing framework.
  • Use MySQL as your database.
  • Type yes when asked to run the default migrations.
  • When prompted “Would you like to run npm install and npm run build?”, type yes.

This will initialize a fresh Laravel 12 project named honeypot, configured to match our setup. With Pest in place for testing and MySQL as the database, we now have a solid starting point to implement and test honeypot protection for our forms, keeping spam submissions out effectively.

Step # 2 : Navigate to the Project.

Open your terminal (such as Git Bash, Command Prompt, or any terminal you're comfortable with) and move into your Laravel project directory. For example
cd c:xampp/htdocs/honeypot
Once you're inside the project folder, you’ll be all set to start running Artisan commands and configuring the application as we move forward.

Step # 3 : Install the Spatie Honeypot Package.

To protect your forms from spam submissions, we’ll use the Spatie Honeypot package. It works by adding hidden fields and checking how quickly a form is submitted, helping block bots without bothering real users. Head over to your project root and run the following command.
composer require spatie/laravel-honeypot
This will pull in the package and make it available for use in your Laravel 12 project. Once installed, adding honeypot protection to your forms becomes a simple and seamless process.

Step # 4 : Publish the Spatie Honeypot Configuration.

Now that the package is installed, the next step is to publish its configuration file. This gives you access to the default settings, which you can customize based on how you want the honeypot to behave, such as changing field names, setting time thresholds, or tweaking protection rules. To publish the config file, run the following Artisan command.
php artisan vendor:publish --provider="Spatie\Honeypot\HoneypotServiceProvider" --tag=honeypot-config
Once published, a new file named honeypot.php will appear inside your project’s config folder. From here, you can fine-tune the spam protection settings to better suit your form and user experience.

Step # 5 : Customize the Honeypot Field Name.

To adjust how honeypot protection works in your application, open the configuration file located at: config/honeypot.phpInside this file, you’ll find the name_field_name option. This sets the name of the hidden honeypot input field, the one bots aren’t supposed to touch. If this field is filled out during form submission, it’s a clear sign of a bot, and the request will be blocked. You can change the field name to something unique. For example, update
From:
'name_field_name' => env('HONEYPOT_NAME', 'my_name')
To:
'name_field_name' => env('HONEYPOT_NAME', 'complete_name'),
Make sure the honeypot field name doesn’t match any real form input fields in your application. This helps avoid any unintentional conflicts when processing user data.

Step # 6 : Create the Contact Form View.

To test the honeypot functionality, let’s build a simple contact form. This form will let users submit their name and a message, and it’s where we’ll later hook in honeypot protection to silently stop spammy bots. Start by creating a new Blade view file at: resources/views/contact.blade.php. Then, add the following code to it.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Laravel - Honeypot - Code Shotcut</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-900 text-white min-h-screen flex items-center justify-center px-4">
    <div class="w-full max-w-xl">
        <h1 class="text-3xl font-extrabold text-center text-white mb-10">
            Code Shotcut Honeypot Example
        </h1>
<!-- Contact Card -->
<div class="bg-gray-800 rounded-lg shadow-lg p-8">
    <h3 class="text-2xl font-bold mb-6 text-white">Contact Us</h3>
    @if(session()->has('success'))
    <div class="bg-green-600 text-white px-4 py-2 rounded mb-4">
        {{ session('success') }}
    </div>
    @endif
    @if(session()->has('error'))
    <div class="bg-red-600 text-white px-4 py-2 rounded mb-4">
        {{ session('error') }}
    </div>
    @endif
    <form method="post" action="{{ url('/message') }}">
        @csrf
        <div class="mb-4">
            <label for="name" class="block text-sm font-semibold mb-2">Name</label>
            <input type="text" name="name" id="name"
            class="w-full px-4 py-2 bg-gray-700 text-white border border-gray-600 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
            placeholder="Enter Name">
        </div>
        <div class="mb-6">
            <label for="message" class="block text-sm font-semibold mb-2">Message</label>
            <textarea name="message" id="message" rows="4"
            class="w-full px-4 py-2 bg-gray-700 text-white border border-gray-600 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
            placeholder="Your Message"></textarea>
        </div>
        <button type="submit"
        class="bg-blue-600 hover:bg-blue-700 text-white font-semibold px-6 py-2 rounded transition">
        Submit
    </button>
</form>
</div>
</div>
</body>
</html>
We’re keeping this form simple on purpose, the goal here is to test how honeypot fields work behind the scenes. This page is where bots will be silently caught before they can interact with your application logic.

Step # 7 : Define Routes and Enable Honeypot Protection.

Next, let’s set up the routes needed for our contact form. We’ll define two routes, one for showing the form, and one for processing the form submission while using the honeypot middleware to catch spam. Start by importing the necessary classes at the top of your routes/web.php file.
use Illuminate\Http\Request;
use Spatie\Honeypot\ProtectAgainstSpam;
Now add the following routes.
// Route to show the contact form
Route::get('/', function () {
    return view('contact');
});
// Route to handle form submission with honeypot protection
Route::post('/message', function (Request $request) {
    $request->validate([
        'name' => 'required|string|max:100',
        'message' => 'required|string|max:500',
    ]);
    return redirect()->back()->with('success', 'Form submitted successfully.');
})->middleware(ProtectAgainstSpam::class);
The GET route displays the contact form for users to fill out, while the POST route handles the submission by validating the input and using the ProtectAgainstSpam middleware to silently block bot requests if the honeypot field is triggered.

Step # 8 : Add Honeypot to the Contact Form.

To enable spam protection, we’ll include the honeypot field in our form. Laravel makes this easy using either a Blade directive or a Blade component, both options will inject hidden fields that bots typically can't resist filling out.
You can use the @honeypot directive like this.
<form method="POST" action="{{ url('/message') }}">
    @csrf
    @honeypot
    <input name="myField" type="text">
</form>
Or, if you prefer Blade components, you can use.
<form method="POST" action="{{ url('/message') }}">
    @csrf
    <x-honeypot />
    <input name="myField" type="text">
</form>
Now let’s apply it to our existing contact form in contact.blade.php. Update the form like so.
<form method="post" action="{{ url('/message') }}">
@csrf
{{-- Add honeypot field to prevent spam bots --}}
@honeypot
<div class="mb-4">
<label for="name" class="block text-sm font-semibold mb-2">Name</label>
<input type="text" name="name" id="name"
class="w-full px-4 py-2 bg-gray-700 text-white border border-gray-600 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Enter Name">
</div>
<div class="mb-6">
<label for="message" class="block text-sm font-semibold mb-2">Message</label>
<textarea name="message" id="message" rows="4"
class="w-full px-4 py-2 bg-gray-700 text-white border border-gray-600 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Your Message."></textarea>
</div>
<button type="submit"
class="bg-blue-600 hover:bg-blue-700 text-white font-semibold px-6 py-2 rounded transition">
Submit
</button>
</form>
When you add @honeypot or <x-honeypot /> to your form, it automatically inserts hidden input fields, typically a name field (like my_name) and a timestamp, based on what's defined in your honeypot.php config file. These fields are hidden from real users through CSS, so they’re never seen or interacted with during normal use. However, bots that try to fill in every available input field will usually target them. If those fields are filled or the form is submitted too quickly, the honeypot middleware will block the request, preventing spam from getting through.

Step # 9 : Time to Test the Honeypot Protection.

Now that everything is set up, let’s run the application and test how honeypot protection behaves in a real form submission. Start the Laravel development server with.
php artisan serve
Access the URL : 127.0.0.1:8000. Inspect the contact form on the page, you should see hidden fields like complete_name and its hashed variant added automatically by the honeypot package.

Try filling out the form like a regular user and hit Submit. If everything’s configured correctly, the form should validate and respond without any errors.


Spam bots will also fill in hidden fields. To see how the honeypot handles spam, manually fill in the hidden field (e.g., complete_name) and submit the form. By default, this will trigger the spam responder and block the submission. You can customize the response for caught spam by editing the BlankPageResponder.php file. For example, to return an error message instead of a blank response, update the class like this.
<?php
namespace Spatie\Honeypot\SpamResponder;
use Closure;
use Illuminate\Http\Request;
class BlankPageResponder implements SpamResponder
{
    public function respond(Request $request, Closure $next)
    {
        return redirect()->back()->with('error', 'Bot detected');
    }
}
This will redirect the user back to the form and flash an error message if a bot is detected.


If you’re using Laravel Breeze, Jetstream, or the default authentication routes, you can apply honeypot protection there too. Just wrap your auth routes inside the honeypot middleware group like so.
use Spatie\Honeypot\ProtectAgainstSpam;
Route::middleware(ProtectAgainstSpam::class)->group(function () {
    Auth::routes();
});
Don’t forget to include the @honeypot directive inside the login and registration forms to make it effective.

Conclusion

By following this guide, you've successfully added honeypot protection to your Laravel 12 application to silently block spam submissions. You created a fresh Laravel project, installed and configured the Spatie Honeypot package, and integrated it into your contact form using Blade. With the honeypot fields in place and the middleware applied, your form is now able to detect and stop automated bots without affecting real users. This approach is lightweight, user-friendly, and easy to reuse across other forms in your app as it grows. You can also build on this by combining it with other validation or spam prevention techniques to further strengthen your application's security.
For more information, don’t forget to check out the official Spatie Honeypot package documentation.
Share this with friends!


"Give this post some love and slap that 💖 button as if it owes you money! 💾😄"
0

0 Comments

To engage in commentary, kindly proceed by logging in or registering