PHPackages                             mkopcic/laravel-bot-protection - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. mkopcic/laravel-bot-protection

ActiveLibrary[Security](/categories/security)

mkopcic/laravel-bot-protection
==============================

Laravel middleware za blokiranje AI crawlera i tražilica. Auto-registracija, konfigurabilan, podržava Laravel 10/11/12/13.

v1.2.2(2w ago)111↓100%MITPHPPHP ^8.1CI passing

Since May 21Pushed 2w agoCompare

[ Source](https://github.com/mkopcic/laravel-bot-protection)[ Packagist](https://packagist.org/packages/mkopcic/laravel-bot-protection)[ RSS](/packages/mkopcic-laravel-bot-protection/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (6)Versions (6)Used By (0)

🤖🛡️ Laravel Bot Protection
==========================

[](#️-laravel-bot-protection)

**Block AI crawlers, search engines, and known scrapers from your Laravel app — with one line of `composer require`.**

[![Latest Version on Packagist](https://camo.githubusercontent.com/028e904180015db2f5b13ce3e625faf85e54fbdd1c619c3ad3786636bb195162/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6b6f706369632f6c61726176656c2d626f742d70726f74656374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/mkopcic/laravel-bot-protection)[![Tests](https://camo.githubusercontent.com/04e7f0fa3ca9570bdc4ce17a615aa88adaaba6427caafd09a1d82883ccd51da8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6b6f706369632f6c61726176656c2d626f742d70726f74656374696f6e2f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/mkopcic/laravel-bot-protection/actions/workflows/tests.yml)[![Total Downloads](https://camo.githubusercontent.com/1446221aeed2bd7c6648060ae552f65a600756f746809baf2971666ce280132f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6b6f706369632f6c61726176656c2d626f742d70726f74656374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/mkopcic/laravel-bot-protection)[![License](https://camo.githubusercontent.com/f0010774d4fd7125f5ab1baba161c4712069d7d924ac23acc87b432c51ee9725/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6d6b6f706369632f6c61726176656c2d626f742d70726f74656374696f6e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![PHP Version](https://camo.githubusercontent.com/eaa0b4b41d1f29f5deb4f3ed0da847c2b0191ecb74301baacedd65eb303c8568/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6d6b6f706369632f6c61726176656c2d626f742d70726f74656374696f6e2e7376673f7374796c653d666c61742d737175617265)](composer.json)[![Laravel](https://camo.githubusercontent.com/9cf2924e1107dfce2f1ce4e149cad74ccace74fa7766e7ffc75fdde112fb89fd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31302532302537432532303131253230253743253230313225323025374325323031332d4646324432303f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c)](composer.json)

---

📖 About
-------

[](#-about)

`laravel-bot-protection` is a drop-in middleware package that protects Laravel applications from unwanted automated traffic — **AI training crawlers, LLM agents, SEO bots, and generic scrapers**. It blocks known bot User-Agents with `HTTP 403` and adds the `X-Robots-Tag: noindex, nofollow` header to every response so well-behaved crawlers (Google, Bing, etc.) also skip indexing.

Built for production apps where you need **zero-config setup** but **fine-grained control** when you want it.

---

✨ Features
----------

[](#-features)

- 🚫 **Blocks 30+ known bots** out of the box — GPTBot, ClaudeBot, PerplexityBot, Bytespider, Google-Extended, CCBot, AhrefsBot, SemrushBot, and more
- ⚡ **Auto-registers globally** — install and you're protected, no manual middleware setup
- 🏷️ **Adds `X-Robots-Tag` header** to every response — covers crawlers that respect HTTP-level directives
- 🎨 **`@botProtectionMeta` Blade directive** — one-liner for `` and `noai/noimageai` tags
- 🤖 **`noai, noimageai` AI opt-out meta tag** — emerging standard adopted by DeviantArt, ArtStation
- 🔄 **Dynamic `/robots.txt` route** (opt-in) — generated from config, single source of truth
- 📡 **`BotBlocked` event** — listen and react: log, alert, feed analytics
- 📝 **Optional logging** — write blocked requests to any Laravel log channel
- 🔧 **Fully configurable** via `.env` or published config — toggle, status code, custom message, allow-list IPs
- 📄 **Publishable `robots.txt`** with comprehensive AI/SEO crawler disallow list
- 🌐 **Server-level config stubs** — Nginx (shared map + per-vhost), Apache vhost, `.htaccess`
- 🧪 **Artisan test command** — verify protection works against a live URL
- ✅ **CI-tested across Laravel 10/11/12/13 × PHP 8.1–8.4** (34 Pest tests)
- 🐘 **Wide compatibility** — Laravel 10 / 11 / 12 / 13, PHP 8.1+

---

📋 Requirements
--------------

[](#-requirements)

RequirementVersionPHP`^8.1`Laravel`10.x`, `11.x`, `12.x`, `13.x`---

📦 Installation
--------------

[](#-installation)

```
composer require mkopcic/laravel-bot-protection
```

That's it. Laravel package auto-discovery registers the service provider and pushes the middleware into the `web` group. Your app is now protected.

### 🎨 Publishing assets (optional)

[](#-publishing-assets-optional)

TagWhat it publishesDestination`bot-protection-config`Configuration file`config/bot-protection.php``bot-protection-robots`Comprehensive `robots.txt``public/robots.txt` ⚠️ overwrites!`bot-protection-server`Nginx + Apache + `.htaccess` snippets`bot-protection/``bot-protection`Config + server stubs (everything except robots.txt)mixed```
# Publish config to customize blocked agents, status codes, etc.
php artisan vendor:publish --tag=bot-protection-config

# Publish robots.txt — heads up, this overwrites your existing one!
php artisan vendor:publish --tag=bot-protection-robots

# Publish Nginx / Apache config examples
php artisan vendor:publish --tag=bot-protection-server
```

---

🚀 Quick Start
-------------

[](#-quick-start)

After installation, verify the protection works:

```
# Show current configuration
php artisan bot-protection:test config

# Test live URL against default bot User-Agents
php artisan bot-protection:test url https://mojaapp.hr

# Test all configured bot agents
php artisan bot-protection:test url https://mojaapp.hr --all
```

You should see `✓ BLOCKED [403]` for each agent.

---

⚙️ Configuration
----------------

[](#️-configuration)

All settings can be controlled via environment variables (no need to publish config):

```
# Master toggle
BOT_PROTECTION_ENABLED=true

# Auto-register middleware into web group
BOT_PROTECTION_AUTO_REGISTER=true

# Which middleware group to attach to
BOT_PROTECTION_MIDDLEWARE_GROUP=web

# What status code to return for blocked bots
BOT_PROTECTION_BLOCK_STATUS=403

# Message body for blocked responses
BOT_PROTECTION_BLOCK_MESSAGE="Forbidden"

# X-Robots-Tag header value (empty string to disable)
BOT_PROTECTION_X_ROBOTS_TAG="noindex, nofollow, noarchive, nosnippet"

# Block requests with empty User-Agent (suspicious)
BOT_PROTECTION_BLOCK_EMPTY_UA=false

# IPs that bypass blocking (comma-separated)
BOT_PROTECTION_ALLOWED_IPS="1.2.3.4,5.6.7.8"

# Log every blocked request as a warning
BOT_PROTECTION_LOG_BLOCKED=false

# Specific log channel (defaults to logging.default)
BOT_PROTECTION_LOG_CHANNEL=daily

# AI opt-out meta tags (rendered by @botProtectionMeta)
BOT_PROTECTION_AI_META_TAGS="noai, noimageai"

# Serve /robots.txt dynamically from blocked_agents config
BOT_PROTECTION_GENERATE_ROBOTS_ROUTE=false
```

For custom blocked agent lists, publish the config and edit `config/bot-protection.php`.

---

🎨 Blade Directive — `@botProtectionMeta`
----------------------------------------

[](#-blade-directive--botprotectionmeta)

Drop one line into your `` and the package renders the standard robots meta tags using your configured `x_robots_tag` value:

```

    My App

    @botProtectionMeta

```

Renders:

```

```

The last `` is the **AI opt-out directive** — an emerging standard adopted by DeviantArt, ArtStation, Squarespace. Some AI scrapers already respect it. Disable via `BOT_PROTECTION_AI_META_TAGS=""`.

If both `x_robots_tag` and `ai_meta_tags` are empty, the directive renders nothing.

---

🔄 Dynamic `/robots.txt` Route
-----------------------------

[](#-dynamic-robotstxt-route)

Instead of publishing a static `public/robots.txt` and keeping it in sync with your config, opt in to a dynamic route:

```
BOT_PROTECTION_GENERATE_ROBOTS_ROUTE=true
```

The package registers `GET /robots.txt` that emits content generated from your `blocked_agents` config. Change the config → robots.txt updates instantly. **Single source of truth.**

> ⚠️ If `public/robots.txt` exists, your web server (Nginx/Apache) serves the static file first and the dynamic route never fires. Delete `public/robots.txt` for full dynamic behavior.

---

📡 `BotBlocked` Event
--------------------

[](#-botblocked-event)

Every block fires a `Mkopcic\BotProtection\Events\BotBlocked` event with full request context. Listen to it for logging, alerting, or analytics:

```
// app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Event;
use Mkopcic\BotProtection\Events\BotBlocked;

public function boot(): void
{
    Event::listen(function (BotBlocked $event) {
        // $event->userAgent     — full UA string
        // $event->ip            — client IP
        // $event->url           — full URL the bot tried
        // $event->matchedAgent  — which needle from blocked_agents matched

        \Log::channel('bots')->info('Blocked', (array) $event);
    });
}
```

Or use a dedicated listener class:

```
php artisan make:listener LogBlockedBot --event="Mkopcic\BotProtection\Events\BotBlocked"
```

---

📝 Built-in Logging
------------------

[](#-built-in-logging)

If you don't need custom event handling, just turn on logging:

```
BOT_PROTECTION_LOG_BLOCKED=true
BOT_PROTECTION_LOG_CHANNEL=daily
```

Every blocked request writes a `warning` to the chosen channel with `user_agent`, `ip`, `url`, and `matched_agent` in the context.

---

🛠️ Manual Middleware Registration
---------------------------------

[](#️-manual-middleware-registration)

If you want full control (e.g. apply only to specific route groups), disable auto-register:

```
BOT_PROTECTION_AUTO_REGISTER=false
```

Then register manually.

**Laravel 11 / 12 / 13** — in `bootstrap/app.php`:

```
use Mkopcic\BotProtection\Http\Middleware\BotProtectionMiddleware;

->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        BotProtectionMiddleware::class,
    ]);
})
```

**Laravel 10** — in `app/Http/Kernel.php`:

```
protected $middlewareGroups = [
    'web' => [
        // ...
        \Mkopcic\BotProtection\Http\Middleware\BotProtectionMiddleware::class,
    ],
];
```

Or apply per-route:

```
Route::middleware(BotProtectionMiddleware::class)->group(function () {
    // protected routes
});
```

---

🧪 Artisan Command — `bot-protection:test`
-----------------------------------------

[](#-artisan-command--bot-protectiontest)

The package ships with a built-in tester with two subactions: `url` and `config`.

### `config` — dump current configuration

[](#config--dump-current-configuration)

```
php artisan bot-protection:test config
```

Outputs all settings, allowed IPs, and the full list of blocked agents.

### `url` — fire HTTP requests with bot User-Agents

[](#url--fire-http-requests-with-bot-user-agents)

```
# Default 3 representative agents (GPTBot, ClaudeBot, PerplexityBot)
php artisan bot-protection:test url https://example.com

# Specific agent
php artisan bot-protection:test url https://example.com --agent=GPTBot

# Test every agent from config
php artisan bot-protection:test url https://example.com --all

# Custom timeout
php artisan bot-protection:test url https://example.com --timeout=30
```

Sample output:

```
Testiranje: https://example.com
Broj agenata: 3

  ✓ BLOCKED [403] GPTBot
  ✓ BLOCKED [403] ClaudeBot
  ✓ BLOCKED [403] PerplexityBot

───────────────────────────────────────
Blocked: 3   Allowed: 0   Errors: 0

```

Returns exit code `0` if all agents are blocked, `1` if any get through.

---

🌐 Server-Level Protection (Recommended)
---------------------------------------

[](#-server-level-protection-recommended)

The middleware protects at the Laravel layer. For **defense in depth**, block bots at the web server too — they never reach PHP, saving CPU.

Publish the server config examples:

```
php artisan vendor:publish --tag=bot-protection-server
```

You'll get a `bot-protection/` directory with:

FileUse`nginx-shared-map.conf`Drop in `/etc/nginx/conf.d/` once — defines `$blocked_bot` map for all vhosts`nginx-vhost-snippet.conf`Paste into each Nginx `server {}` block`apache-vhost-snippet.conf`Full Apache vhost example with `SetEnvIf``htaccess-snippet.txt``.htaccess` rules (when you can't edit vhosts)---

🧬 How It Works
--------------

[](#-how-it-works)

```
   ┌─────────────────────┐
   │  Incoming Request   │
   └──────────┬──────────┘
              ▼
   ┌────────────────────────┐
   │   Web Server           │  ← optional: blocks at nginx/apache layer
   │   (nginx/apache)       │
   └──────────┬─────────────┘
              ▼
   ┌────────────────────────┐
   │  BotProtection         │
   │  Middleware            │
   │                        │
   │  1. Check enabled?     │
   │  2. IP in allow-list?  │
   │  3. UA matches bot?    │──── YES ──▶  HTTP 403
   │  4. Empty UA + flag?   │
   └──────────┬─────────────┘
              │ NO
              ▼
   ┌────────────────────────┐
   │   Laravel App          │
   └──────────┬─────────────┘
              ▼
   ┌────────────────────────┐
   │  Response              │
   │  + X-Robots-Tag header │
   └────────────────────────┘

```

---

🧪 Running Tests
---------------

[](#-running-tests)

```
composer install
./vendor/bin/pest
```

13 Pest tests cover:

- ✅ Blocking known bot User-Agents
- ✅ Allowing legitimate browser User-Agents
- ✅ Adding `X-Robots-Tag` header to passed responses
- ✅ Case-insensitive User-Agent matching
- ✅ `enabled=false` bypass
- ✅ Custom block status codes
- ✅ Custom block messages
- ✅ Empty `x_robots_tag` disables header
- ✅ Empty User-Agent handling (both modes)
- ✅ Allowed-IP bypass

---

🤖 What's Blocked Out of the Box
-------------------------------

[](#-whats-blocked-out-of-the-box)

**Click to expand the full list (33 agents)**CategoryAgents**OpenAI**GPTBot, ChatGPT-User, OAI-SearchBot**Anthropic**ClaudeBot, anthropic-ai, Claude-Web**Google**Google-Extended, Googlebot, AdsBot-Google**Meta**Meta-ExternalAgent, FacebookBot, facebookexternalhit**Apple**Applebot, Applebot-Extended**Amazon**Amazonbot**Perplexity**PerplexityBot**ByteDance**Bytespider**Common Crawl**CCBot**Cohere**cohere-ai**Mistral**MistralAI-User**Diffbot**Diffbot**SEO crawlers**SemrushBot, AhrefsBot, MJ12bot, DotBot, BLEXBot**Eastern engines**YandexBot, Baiduspider, Sogou**Generic scrapers**Scrapy, python-requests, curl/, wget/You can add, remove, or fully override the list by publishing config and editing `blocked_agents`.

---

⚠️ What This Package Is NOT
---------------------------

[](#️-what-this-package-is-not)

- ❌ **Not authentication.** If content must be private, use Laravel auth, Basic Auth, or Cloudflare Zero Trust.
- ❌ **Not foolproof against UA spoofing.** A determined scraper can fake any User-Agent. This package targets mass crawlers that identify themselves correctly.
- ❌ **Not a WAF.** For rate limiting, geo-blocking, DDoS protection, layer in Cloudflare or a dedicated WAF.

For maximum protection: **this package + server-level rules + authentication for sensitive content.**

---

🔗 Related
---------

[](#-related)

- 📖 [Google: Robots meta tag and X-Robots-Tag specifications](https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag)
- 📖 [OpenAI: GPTBot opt-out documentation](https://platform.openai.com/docs/gptbot)
- 📖 [Cloudflare: Block AI bots and scrapers](https://blog.cloudflare.com/declaring-your-aindependence-block-ai-bots-scrapers-and-crawlers-with-a-single-click/)

---

🤝 Contributing
--------------

[](#-contributing)

Contributions are welcome! Please open an issue or PR.

For new bot User-Agents to add to the default list, please include a source link (the bot's official documentation page).

---

📜 License
---------

[](#-license)

The MIT License (MIT). See [LICENSE](LICENSE) for details.

---

**Built with ❤️ for the Laravel community.**

If this package saved your bandwidth or your sanity, ⭐ the repo!

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance96

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

5

Last Release

18d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/884b747f0c5cf34ebe1216c2b425c58e06180cb0fccb1a75e8ac8fdeea00acad?d=identicon)[mkopcic](/maintainers/mkopcic)

---

Top Contributors

[![mkopcic](https://avatars.githubusercontent.com/u/6863769?v=4)](https://github.com/mkopcic "mkopcic (7 commits)")

---

Tags

middlewarelaravelaicrawlerbotseorobotsclaudegptprivacy

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/mkopcic-laravel-bot-protection/health.svg)

```
[![Health](https://phpackages.com/badges/mkopcic-laravel-bot-protection/health.svg)](https://phpackages.com/packages/mkopcic-laravel-bot-protection)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

76318.2M110](/packages/laravel-mcp)[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k8.7M64](/packages/spatie-laravel-responsecache)[laravel/surveyor

Static analysis tool for Laravel applications.

8390.3k12](/packages/laravel-surveyor)[api-platform/laravel

API Platform support for Laravel

59156.3k10](/packages/api-platform-laravel)[calebdw/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

15104.9k4](/packages/calebdw-larastan)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
