Generate Laravel CORS configurations and Nginx location blocks for your SPA/SSR applications. Configure allowed origins, methods, cache headers, and more with our free wizard.
Configure CORS settings and Nginx location blocks for your Laravel SPA/SSR application
Your Laravel CORS and Nginx configurations are ready to use.
config/cors.php
bootstrap/app.php
php artisan config:cache
to cache the configurationnginx -t
nginx -s reload
Laravel Boilerplate
The first Laravel boilerplate built for vibe coding. 200+ pre-built features, multiple payment processors, and Cursor-optimized code.
Cross-Origin Resource Sharing (CORS) is a critical security feature that controls how web applications interact with resources from different domains. When building modern Laravel applications with Single Page Applications (SPAs) or serving APIs to external clients, proper CORS configuration becomes essential for functionality and security. Combined with Nginx as a reverse proxy, you can create robust, secure, and performant web applications.
Our Laravel CORS/Nginx Configuration Wizard simplifies the process of setting up proper CORS and Nginx configurations for your applications. Based on real-world issues and best practices, our tool generates production-ready configurations that address common problems developers face.
Cross-Origin Resource Sharing (CORS) is a web security feature implemented by web browsers that blocks requests from one domain to another unless the server explicitly allows it. This security mechanism prevents malicious websites from making unauthorized requests to other domains on behalf of users. In modern web development, especially when building Laravel applications that serve APIs or work with Single Page Applications (SPAs), understanding and properly configuring CORS is essential.
The same-origin policy, which CORS extends, ensures that a web page can only access resources from the same origin (same protocol, domain, and port). However, modern applications often need to make requests across different origins, such as when a React frontend hosted on one domain needs to communicate with a Laravel API hosted on another domain. This is where CORS configuration becomes crucial.
Laravel 12 provides built-in CORS support through the fruitcake/laravel-cors
package, which is included by default. The CORS configuration is managed through the config/cors.php
file, where you can define various CORS policies for your application. Laravel 12's streamlined architecture makes CORS configuration even more straightforward.
In Laravel 12, middleware registration is handled through the bootstrap/app.php
file instead of the traditional app/Http/Kernel.php
. This simplifies the configuration process and provides better performance.
// bootstrap/app.php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
// Register CORS middleware for API routes
$middleware->api(prepend: [
\Fruitcake\Cors\HandleCors::class,
]);
// Or register globally
$middleware->append(\Fruitcake\Cors\HandleCors::class);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
When a browser makes a "complex" request (one that includes custom headers, uses methods other than GET/POST, or has specific content types), it first sends a preflight OPTIONS request to check if the actual request is allowed. The server responds with CORS headers indicating what's permitted. This two-step process ensures security while allowing legitimate cross-origin requests.
Nginx serves as an excellent reverse proxy and web server for Laravel applications. When properly configured, it can handle static file serving, SSL termination, load balancing, and CORS headers at the server level. This approach can improve performance by handling CORS at the Nginx level before requests even reach your Laravel application.
Nginx location blocks allow you to handle different types of requests with specific configurations. For Laravel applications, you typically need location blocks for static assets, API routes, and general application routes. Each can have its own CORS and caching policies.
When serving Single Page Applications with Laravel, you need to handle both the initial HTML delivery and subsequent API calls. SPAs often use client-side routing, which means the server needs to serve the main HTML file for all routes that don't correspond to actual files or API endpoints. This is commonly called the "fallback" or "catch-all" route.
The SPA fallback ensures that when users navigate directly to a client-side route (like /dashboard/users
), the server serves the main HTML file instead of returning a 404 error. This allows the client-side router to take over and display the correct page. Nginx can handle this efficiently with a simple try_files directive.
While CORS is essential for functionality, it must be configured securely to prevent abuse. Here are key security considerations:
Proper CORS and Nginx configuration can significantly impact your application's performance. Here are optimization strategies:
Misconfigurations in CORS settings can lead to security vulnerabilities and functionality issues. Here are the most common problems developers encounter and how to fix them:
Using wildcard (*
) in allowed_origins
permits any domain to access your resources, which can be risky in production environments.
❌ Incorrect:
'allowed_origins' => ['*']
✅ Correct:
'allowed_origins' => ['https://trusted-frontend.com']
Combining allowed_origins
set to *
with supports_credentials
set to true
violates the CORS specification and can expose sensitive information.
❌ Incorrect:
'allowed_origins' => ['*'],
'supports_credentials' => true
✅ Correct:
'allowed_origins' => ['https://trusted-frontend.com'],
'supports_credentials' => true
Allowing all HTTP methods can expose your application to unintended actions and potential security risks.
❌ Incorrect:
'allowed_methods' => ['*']
✅ Correct:
'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH']
Allowing all headers can lead to security risks if unexpected headers are accepted by your application.
❌ Incorrect:
'allowed_headers' => ['*']
✅ Correct:
'allowed_headers' => ['Content-Type', 'X-Requested-With', 'Authorization']
Ensure that the CORS middleware is correctly registered in your Laravel application. In Laravel 12, this is handled through the bootstrap/app.php
file.
✅ Correct Middleware Registration:
// In bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->api(prepend: [
\Fruitcake\Cors\HandleCors::class,
]);
})
Laravel 12 introduced significant changes to middleware registration and CORS handling. Based on real-world issues reported by developers, here are the most common problems and their solutions:
Problem: CORS headers are not being sent even though the configuration appears correct.
❌ Common Mistake:
// Wrong - using append() globally
->withMiddleware(function (Middleware $middleware) {
$middleware->append(\Illuminate\Http\Middleware\HandleCors::class);
})
✅ Correct Solution:
// Correct - use prepend() to run CORS before everything else
->withMiddleware(function (Middleware $middleware) {
$middleware->prepend(\Illuminate\Http\Middleware\HandleCors::class);
// Or specifically for API routes
$middleware->appendToGroup('api', \Illuminate\Http\Middleware\HandleCors::class);
})
Problem: Browser preflight requests return "No 'Access-Control-Allow-Origin' header is present" error.
🔧 Debugging Steps:
curl -I -X OPTIONS https://your-api.com/api/endpoint
php artisan route:list
php artisan optimize:clear
Problem: CORS headers only work for some routes but not others.
✅ Correct Paths Configuration:
// config/cors.php
'paths' => [
'api/*', // All API routes
'sanctum/csrf-cookie', // Laravel Sanctum
'api/v1/*', // Versioned API routes
'api/v2/*', // Multiple API versions
],
Problem: CORS works in development but fails in production.
✅ Environment-Specific Configuration:
// config/cors.php
'allowed_origins' => [
// Development
'http://localhost:3000',
'http://localhost:5173',
'http://127.0.0.1:8000',
// Production
'https://yourdomain.com',
'https://app.yourdomain.com',
// Staging
'https://staging.yourdomain.com',
],
Laravel 12's new middleware registration system can be confusing. Here's how to properly register CORS middleware:
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
// Run CORS before everything else
$middleware->prepend(\Illuminate\Http\Middleware\HandleCors::class);
})
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
// Only for API routes
$middleware->appendToGroup('api', \Illuminate\Http\Middleware\HandleCors::class);
})
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
// Only in non-production environments
if (!app()->environment('production')) {
$middleware->prepend(\Illuminate\Http\Middleware\HandleCors::class);
}
})
Preflight requests are OPTIONS requests that browsers send before making certain cross-origin requests. Here's how to handle them properly:
Browsers send preflight requests when:
🔧 Testing Commands:
# Test preflight request
curl -I -X OPTIONS \
-H "Origin: https://yourdomain.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Content-Type" \
https://your-api.com/api/endpoint
# Expected response headers:
# Access-Control-Allow-Origin: https://yourdomain.com
# Access-Control-Allow-Methods: POST, GET, OPTIONS
# Access-Control-Allow-Headers: Content-Type
# Access-Control-Max-Age: 3600
Different environments require different CORS configurations. Here's how to handle this properly:
// config/cors.php
return [
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => [
// Development
'http://localhost:3000',
'http://localhost:5173',
'http://127.0.0.1:8000',
// Production
'https://yourdomain.com',
'https://app.yourdomain.com',
],
'allowed_origins_patterns' => [
// Allow all subdomains in development
'/^https?:\/\/localhost:\d+$/',
'/^https?:\/\/127\.0\.0\.1:\d+$/',
],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 3600,
'supports_credentials' => false,
];
// config/cors.php
'allowed_origins' => array_filter([
env('FRONTEND_URL', 'http://localhost:3000'),
env('ADMIN_URL', 'http://localhost:3001'),
env('APP_URL'),
// Add more as needed
]),
Some applications require more complex CORS configurations. Understanding these advanced scenarios helps you build robust, scalable applications.
Applications with multiple subdomains (api.example.com, app.example.com, admin.example.com) need careful CORS configuration. You can use pattern matching or maintain separate configurations for each subdomain. Consider using a wildcard subdomain pattern like *.example.com
if your security requirements allow it.
Some applications need to validate origins dynamically based on user permissions or other business logic. Laravel allows you to implement custom CORS logic by extending the default CORS middleware or creating custom middleware that handles origin validation based on your application's requirements.
When integrating with third-party services, you may need to configure CORS to allow requests from their domains. This is common with payment processors, analytics services, or other external APIs. Always verify the legitimacy of third-party origins and implement proper validation.
Proper testing ensures your CORS configuration works correctly across different scenarios. Here are testing strategies and tools:
Modern browsers provide excellent CORS debugging tools. The Network tab shows preflight requests and responses, while the Console displays CORS error messages. Use these tools to verify that CORS headers are being sent correctly and that requests are not being blocked.
Include CORS testing in your automated test suite. Test different origins, methods, and headers to ensure your configuration works as expected. Consider using tools like Postman or curl to test API endpoints with different CORS scenarios.
Different browsers may handle CORS slightly differently. Test your application across major browsers to ensure consistent behavior. Pay special attention to older browser versions that might have different CORS implementations.
Effective monitoring helps you identify and resolve CORS issues quickly. Implement logging and monitoring for CORS-related events.
Log CORS-related events, including blocked requests, preflight failures, and origin validation results. This information helps you understand how your CORS configuration is performing and identify potential issues before they affect users.
Use error tracking services to monitor CORS-related errors in production. Services like Sentry, Bugsnag, or Rollbar can help you identify patterns in CORS failures and provide context for debugging.
CORS (Cross-Origin Resource Sharing) is a security feature that controls how web applications interact with resources from different domains. You need it when your frontend and backend are on different domains, or when building APIs that will be consumed by external applications. Without CORS, browsers block cross-origin requests by default to prevent malicious websites from accessing your data.
Laravel 12 uses the fruitcake/laravel-cors
package by default. Configure it in config/cors.php
and register the middleware in bootstrap/app.php
using $middleware->prepend(\Illuminate\Http\Middleware\HandleCors::class)
to ensure it runs before other middleware.
Common issues include: 1) Using append()
instead of prepend()
for middleware registration, 2) Not clearing cache after configuration changes, 3) Incorrect paths configuration, 4) Missing allowed origins. Always use php artisan optimize:clear
after making changes.
Simple requests (GET, POST with basic content types) don't trigger preflight. Complex requests (custom headers, PUT/DELETE methods, non-standard content types) trigger a preflight OPTIONS request that the server must handle before the actual request. Preflight requests must return proper CORS headers or the browser will block the actual request.
Use browser developer tools to inspect network requests and responses. Test with different origins, methods, and headers. Use tools like Postman or curl to simulate cross-origin requests. Include CORS testing in your automated test suite. Test preflight requests with: curl -I -X OPTIONS -H "Origin: https://yourdomain.com" https://your-api.com/api/endpoint
Both approaches have benefits. Nginx-level CORS is more performant and handles all requests consistently. Laravel-level CORS provides more flexibility and can be environment-specific. Many applications use both: Nginx for static assets and Laravel for API routes.
Common causes include missing or incorrect CORS headers, using wildcard origins with credentials, not handling preflight OPTIONS requests, or having mismatched allowed methods/headers. Check your browser's developer tools for specific error messages. In Laravel 12, ensure you're using prepend()
instead of append()
for middleware registration.
Use environment-based configuration. Define different allowed origins for development, staging, and production in your .env file or configuration files. Laravel's config system makes this easy with environment-specific settings. Use env()
helper in your cors.php config file.
In Laravel 12, register CORS middleware in bootstrap/app.php
using $middleware->prepend(\Illuminate\Http\Middleware\HandleCors::class)
to ensure it runs before other middleware. You can also use appendToGroup('api', ...)
for API-specific routes.
1) Check middleware registration order, 2) Test with curl commands, 3) Clear all caches with php artisan optimize:clear
, 4) Restart PHP-FPM, 5) Check browser developer tools, 6) Verify paths configuration matches your routes, 7) Test preflight requests specifically.
You can use wildcard for allowed origins, but it's not recommended for production applications, especially when using credentials. Wildcard origins don't work with credentials, and they can be a security risk. Use specific domain names instead. For development, consider using allowed_origins_patterns
with regex patterns.
While you can use more permissive CORS settings for development, it's better to mirror your production configuration as closely as possible. This helps catch CORS issues early and ensures your development environment behaves like production. Use environment-specific configurations instead of disabling CORS entirely.
When using authentication, you must set supports_credentials
to true and cannot use wildcard origins. The client must include credentials in requests, and you need to handle preflight requests properly for authenticated endpoints. Always specify exact origins when using credentials.
CORS adds minimal overhead, but preflight requests can impact performance if not handled efficiently. Use appropriate max-age values for preflight caching, handle OPTIONS requests at the server level, and consider using simple requests when possible to avoid preflight. Nginx-level CORS can improve performance by handling it before requests reach Laravel.
Laravel Sanctum requires specific CORS configuration. Include sanctum/csrf-cookie
in your paths, set supports_credentials
to true, and ensure your frontend sends credentials with requests. Configure allowed origins specifically for your frontend domain.
allowed_origins
accepts exact domain matches, while allowed_origins_patterns
accepts regex patterns for dynamic matching. Use patterns for subdomains or dynamic domains. Example: '/^https?:\/\/([a-z0-9-]+\.)?yourdomain\.com$/'
matches all subdomains.
This error means CORS headers aren't being sent. Check: 1) Middleware registration order (use prepend()
), 2) Paths configuration matches your routes, 3) Clear cache with php artisan optimize:clear
, 4) Restart PHP-FPM, 5) Test with curl to verify headers are present.
Yes, Laravel Passport works with CORS. Configure CORS to allow your frontend domain, set supports_credentials
to true, and ensure your frontend includes credentials in requests. Include OAuth routes in your paths configuration if needed.
Mobile apps typically don't have CORS restrictions since they're not browsers. However, if your mobile app uses WebView components, you may need CORS configuration. For native mobile apps, focus on proper API authentication and rate limiting instead of CORS.