When working with Laravel 12 and building APIs consumed by frontend apps (like React, Vue, etc.), you might run into the dreaded CORS error — even when you think you’ve configured it correctly.
I did everything Laravel told me to do, but CORS was still broken. Eventually, I found a fix using custom middleware, and I’m sharing it here so you don’t waste hours like I did.
The Problem
I kept seeing this CORS error in the browser:
Access to fetch at 'http://example.com/api/...'
from origin 'http://localhost:3000'
has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Even though I had this set in config/cors.php:
'paths' => ['api/*'],
'allowed_origins' => ['*'],
'supports_credentials' => true,
Nothing worked. Laravel’s built-in HandleCors middleware wasn’t doing its job.
The Solution (Custom Middleware)
Instead of relying on Laravel’s built-in CORS system, I created my own middleware and manually registered it.
Step 1: Create Middleware
php artisan make:middleware Cors
Then open the file at app/Http/Middleware/Cors.php
and paste this:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class Cors
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->header('Access-Control-Allow-Origin', '*');
$response->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
$response->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization');
return $response;
}
}
Step 2: Register Middleware in Laravel 12
In Laravel 12,Http\Kernel.php
is gone — so you register middleware in bootstrap/app.php
instead.
If you want it applied globally to all requests:
$app->middleware([
\App\Http\Middleware\Cors::class,
]);
If you want to apply it only to certain routes:
$app->routeMiddleware([
'cors.custom' => \App\Http\Middleware\Cors::class,
]);
Step 3: Apply It to Routes (if route-based)
In your routes/api.php
file:
Route::middleware(['cors.custom'])->group(function () {
Route::get('/example', [ExampleController::class, 'index']);
});
Why This Works
Laravel’s default CORS middleware can sometimes silently fail due to misconfiguration or changes in the request flow. By taking full control with a custom middleware, you ensure the correct headers are returned with every response.
This is especially useful when:
- You’re using Laravel 12’s minimal setup
- You’re building SPAs or frontends on a different domain
- The default config doesn’t work even after clearing caches
Final Thoughts
CORS issues are frustrating, and Laravel’s magic sometimes gets in the way. This manual solution worked for me and might help you too.
Let me know if this helped — or if you have a cleaner workaround!
Top comments (2)
$response->header('Access-Control-Allow-Origin', '*');
That is the worst advise you can give. CORS helps to secure your website data. And with that line you are opening all urls for everyone to use.
Agreed but I believe he suggested it as a general solution. Anyone can set it as per their requirements