Laravel Middleware insertBefore &amp; insertAfter (13.40) | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://msaied.com) - [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [About](https://msaied.com#about)

           [  Contact](https://msaied.com#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://msaied.com)
- [ProjectsCase studies](https://msaied.com/projects)
- [ArticlesEngineering notes](https://msaied.com/articles)
- [CertificatesCredentials](https://msaied.com/certificates)
- [AboutHow I work](https://msaied.com#about)
- [ContactGet in touch](https://msaied.com#contact)

  [Start a conversation](https://msaied.com#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://msaied.com)
2. /
3. [Articles](https://msaied.com/articles)
4. /
5. [Laravel](https://msaied.com/articles?category=laravel)
6. /
7. Insert Middleware Before or After Existing Laravel Middleware (Laravel 13.40)

   [Laravel](https://msaied.com/articles?category=laravel) [Tips &amp; Tricks](https://msaied.com/articles?category=tips-tricks) 

 Insert Middleware Before or After Existing Laravel Middleware (Laravel 13.40)
==============================================================================

 Laravel 13.40 adds insertBefore(), insertAfter(), insertBeforeInGroup(), and insertAfterInGroup() so you can place custom middleware at an exact position in the global stack or a middleware group without redefining the whole list.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://msaied.com#person) Published 6 Nov 2026 · Updated 10 Nov 2026 · 3 min read

ShareCopy linkCopied

 ![Insert Middleware Before or After Existing Laravel Middleware (Laravel 13.40)](https://cdn.msaied.com/821/88459f9998da0239229cdbcb6f7daa6c.png) 

  On this page +1. [The Problem With prepend() and append()](#the-problem-with-codeprependcode-and-codeappendcode)
2. [New Methods in Laravel 13.40](#new-methods-in-laravel-1340)
3. [Global Stack: insertBefore() and insertAfter()](#global-stack-codeinsertbeforecode-and-codeinsertaftercode)
4. [Middleware Groups: insertBeforeInGroup() and insertAfterInGroup()](#middleware-groups-codeinsertbeforeingroupcode-and-codeinsertafteringroupcode)
5. [replace() Now Accepts an Array](#codereplacecode-now-accepts-an-array)
6. [Real-World Example: Locale From the Session](#real-world-example-locale-from-the-session)
7. [Real-World Example: Blocking Banned IPs](#real-world-example-blocking-banned-ips)
8. [Key Takeaways](#key-takeaways)

 The Problem With `prepend()` and `append()`
-------------------------------------------

Some middleware must run at a very specific point in the request lifecycle. A middleware that reads `$request->ip()` needs to run *after* `TrustProxies` so it sees the real client address, not the load balancer's. A middleware that reads the session needs to run *after* `StartSession`. One that changes how route models resolve needs to run *before* `SubstituteBindings`.

Before Laravel 13.40, `withMiddleware()` in `bootstrap/app.php` could only push middleware to the start or end of the global stack or a group. Getting a middleware into the exact right slot meant redefining the entire group by hand — a copy that silently drifts out of sync every time the framework updates its own list.

New Methods in Laravel 13.40
----------------------------

### Global Stack: `insertBefore()` and `insertAfter()`

These two methods target the global middleware stack. The first argument is the anchor middleware; the second is the middleware (or an array of them) to insert:

```php
use App\Http\Middleware\BlockBannedIps;
use App\Http\Middleware\SanitizeInput;
use Illuminate\Foundation\Http\Middleware\TrimStrings;
use Illuminate\Http\Middleware\TrustProxies;

->withMiddleware(function (Middleware $middleware) {
    $middleware->insertAfter(TrustProxies::class, BlockBannedIps::class);
    $middleware->insertBefore(TrimStrings::class, SanitizeInput::class);
})

```

### Middleware Groups: `insertBeforeInGroup()` and `insertAfterInGroup()`

The group variants take the group name as the first argument:

```php
use App\Http\Middleware\SetLocaleFromSession;
use Illuminate\Session\Middleware\StartSession;

->withMiddleware(function (Middleware $middleware) {
    $middleware->insertAfterInGroup('web', StartSession::class, SetLocaleFromSession::class);
})

```

This works on any group, including custom ones you define with `$middleware->group()`.

### `replace()` Now Accepts an Array

The same release lets `replace()` and `replaceInGroup()` accept an array of middleware in place of a single class. The array replaces the original middleware's slot in the stack:

```php
// Insert StripCrossOriginReferer immediately after TrustProxies
$middleware->replace(TrustProxies::class, [
    TrustProxies::class,
    StripCrossOriginReferer::class,
]);

```

The `web()` and `api()` helpers pass their `replace` argument to `replaceInGroup()`, so arrays work there too:

```php
$middleware->web(replace: [
    StartSession::class => [StartSession::class, SetLocaleFromSession::class],
]);

```

Real-World Example: Locale From the Session
-------------------------------------------

An application that stores the user's language in the session and resolves route model bindings by localized slug needs `SetLocaleFromSession` to run *after* `StartSession` and *before* `SubstituteBindings`. The old workaround was to copy the entire `web` group — a list that changed between Laravel 12 (`ValidateCsrfToken`) and Laravel 13 (`PreventRequestForgery`), silently breaking upgrades.

With 13.40:

```php
->withMiddleware(function (Middleware $middleware) {
    $middleware->insertAfterInGroup('web', StartSession::class, SetLocaleFromSession::class);
})

```

The resulting group order is: `EncryptCookies` → `AddQueuedCookiesToResponse` → `StartSession` → `SetLocaleFromSession` → `ShareErrorsFromSession` → `PreventRequestForgery` → `SubstituteBindings`.

Real-World Example: Blocking Banned IPs
---------------------------------------

A `BlockBannedIps` middleware that calls `$request->ip()` must run after `TrustProxies`. Using `prepend()` puts it before proxy trust; using `append()` puts it too late in the pipeline. The fix is a single line:

```php
$middleware->insertAfter(TrustProxies::class, BlockBannedIps::class);

```

Key Takeaways
-------------

- **`insertBefore()` / `insertAfter()`** — place middleware at an exact position in the global stack.
- **`insertBeforeInGroup()` / `insertAfterInGroup()`** — same precision inside any named middleware group.
- **`replace()` now accepts an array** — swap one middleware for multiple in a single call.
- Avoid copying entire group definitions; the new methods stay in sync as the framework evolves.
- Contributed by Jamie York in PRs [\#62230](https://github.com/laravel/framework/pull/62230) and [\#62261](https://github.com/laravel/framework/pull/62261).

---

*Source: [Insert Middleware Before or After Existing Laravel Middleware — Laravel News](https://laravel-news.com/laravel-middleware-insert-before-after)*

- [Laravel](https://msaied.com/articles?search=Laravel)
- [Middleware](https://msaied.com/articles?search=Middleware)
- [Laravel 13](https://msaied.com/articles?search=Laravel%2013)
- [PHP](https://msaied.com/articles?search=PHP)
- [Backend](https://msaied.com/articles?search=Backend)

 Frequently asked questions 
---------------------------

  What is the difference between insertAfter() and insertAfterInGroup() in Laravel 13.40?insertAfter() targets the global middleware stack, while insertAfterInGroup() targets a specific named middleware group such as 'web' or 'api'. Both accept the anchor middleware class as the first argument and the middleware to insert as the second.

   Why is copying the entire web middleware group a bad practice?A manually copied group does not follow framework changes. For example, Laravel 12 used ValidateCsrfToken while Laravel 13 uses PreventRequestForgery. A copied list will silently keep the old class after upgrading and may also drop middleware added dynamically, such as the one added by authenticateSessions().

   Can replace() now insert multiple middleware in place of one?Yes. As of Laravel 13.40, replace() and replaceInGroup() accept an array. The entire array takes the original middleware's position in the stack, so you can effectively insert one or more middleware at a precise location by including the original class in the array alongside the new ones.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://msaied.com#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://msaied.com#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleLaravel Herd 2: Coding Agents, Workspaces, and Cloud Deploys](https://msaied.com/articles/laravel-herd-2-coding-agents-workspaces-and-cloud-deploys)  

   On this page
-------------

1. [The Problem With prepend() and append()](#the-problem-with-codeprependcode-and-codeappendcode)
2. [New Methods in Laravel 13.40](#new-methods-in-laravel-1340)
3. [Global Stack: insertBefore() and insertAfter()](#global-stack-codeinsertbeforecode-and-codeinsertaftercode)
4. [Middleware Groups: insertBeforeInGroup() and insertAfterInGroup()](#middleware-groups-codeinsertbeforeingroupcode-and-codeinsertafteringroupcode)
5. [replace() Now Accepts an Array](#codereplacecode-now-accepts-an-array)
6. [Real-World Example: Locale From the Session](#real-world-example-locale-from-the-session)
7. [Real-World Example: Blocking Banned IPs](#real-world-example-blocking-banned-ips)
8. [Key Takeaways](#key-takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://msaied.com#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/818/b17de0c62dc689581d4135b9cb797240.png) Laravel · 4 min read### Laravel Herd 2: Coding Agents, Workspaces, and Cloud Deploys

5 Nov 2026 ](https://msaied.com/articles/laravel-herd-2-coding-agents-workspaces-and-cloud-deploys) [ ![](https://cdn.msaied.com/820/d87884969c96b6d38c264c4213db8d12.png) Laravel · 4 min read### Strict Request Input Casting in Laravel 13.40

5 Nov 2026 ](https://msaied.com/articles/strict-request-input-casting-in-laravel-1340) [ ![](https://cdn.msaied.com/817/1f6e0273ce6e6ecf37ad8c7616c60135.png) Laravel · 4 min read### Post Mortem: How Laravel Patched PHP and Node.js Vulnerabilities Across Its Entire Fleet

4 Nov 2026 ](https://msaied.com/articles/post-mortem-how-laravel-patched-php-and-nodejs-vulnerabilities-across-its-entire-fleet) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://msaied.com#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://msaied.com)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://msaied.com/sitemap.xml)
