Laravel CORS/Nginx

Configuration Wizard

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.

Laravel CORS & Nginx Configuration

Configure CORS settings and Nginx location blocks for your Laravel SPA/SSR application

CORS Configuration

One origin per line. Never use * in production!

Routes where CORS should be applied

⚠️ Cannot use wildcard origins when enabled

Nginx Configuration

Configuration Generated Successfully!

Your Laravel CORS and Nginx configurations are ready to use.

Laravel CORS Configuration (config/cors.php)

Nginx Configuration

Installation Instructions

1. Laravel 12 CORS Setup:
  • Save the CORS configuration to config/cors.php
  • Ensure the CORS middleware is registered in bootstrap/app.php
  • Run php artisan config:cache to cache the configuration
2. Nginx Setup:
  • Add the Nginx configuration to your server block
  • Test the configuration with nginx -t
  • Reload Nginx with nginx -s reload
Stack Toast - Laravel Boilerplate

Stack Toast

Laravel Boilerplate

Launch Your SaaS in Days, Not Months

The first Laravel boilerplate built for vibe coding. 200+ pre-built features, multiple payment processors, and Cursor-optimized code.

Laravel 12 Ready
Cursor Optimized
Launch in Days
No Setup Hassles

Everything You Need

200+ Ready Features
Pre-built & tested
100+ AI Models
Integrated & ready
4 Payment Gateways
Stripe, Paddle, Lemon Squeezy, Coinbase
0 Headaches
Just start building

Complete Guide to Laravel CORS and Nginx Configuration

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.

Getting Started with Our CORS/Nginx Wizard

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.

Why Use Our Wizard?

  • Laravel 12 Ready: Generates configurations specifically for Laravel 12's new middleware system
  • Security First: Follows security best practices and avoids common misconfigurations
  • Real-World Tested: Based on solutions to actual problems reported by developers
  • Performance Optimized: Includes Nginx configurations for better performance
  • Environment Aware: Handles development, staging, and production configurations

How to Use the Wizard

  1. Configure CORS Settings: Enter your allowed origins, methods, and headers
  2. Set Nginx Options: Configure server name, asset paths, and caching
  3. Generate Configurations: Click the generate button to create your configs
  4. Copy and Implement: Copy the generated configurations to your project
  5. Test and Deploy: Test locally before deploying to production

💡 Pro Tips for Using the Wizard

  • Start with permissive settings for testing, then tighten security for production
  • Always test your configuration with curl commands before deploying
  • Use environment variables for different deployment environments
  • Clear Laravel cache after making configuration changes
  • Monitor your application logs for CORS-related errors

Understanding CORS in Modern Web Development

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 CORS Configuration Deep Dive

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.

Laravel 12 CORS Middleware Registration

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();

Key CORS Configuration Options

  • Paths: Define which routes should have CORS headers applied
  • Allowed Methods: Specify which HTTP methods are permitted (GET, POST, PUT, DELETE, etc.)
  • Allowed Origins: List the domains that can make requests to your API
  • Allowed Headers: Define which headers clients can send with requests
  • Exposed Headers: Specify which headers clients can access in responses
  • Max Age: Set how long browsers can cache preflight responses
  • Supports Credentials: Allow cookies and authorization headers in requests

CORS Preflight Requests

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 Configuration for Laravel Applications

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 CORS Implementation Benefits

  • Performance: CORS headers are added at the server level, reducing PHP processing overhead
  • Consistency: All responses get CORS headers, regardless of Laravel middleware configuration
  • Security: Can implement additional security headers alongside CORS
  • Flexibility: Different CORS policies for different location blocks
  • Caching: Static assets can be served with appropriate CORS headers and caching policies

Nginx Location Blocks for Laravel

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.

Single Page Application (SPA) Considerations

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.

SPA Fallback Configuration

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.

Security Best Practices

While CORS is essential for functionality, it must be configured securely to prevent abuse. Here are key security considerations:

Origin Validation

  • Never use wildcard (*) for allowed origins in production
  • Use specific domain names or subdomains
  • Consider using environment-based configuration for different stages
  • Implement origin validation in your application logic when needed

Header Security

  • Only allow necessary headers in requests
  • Be cautious with credentials support - only enable when needed
  • Use appropriate max-age values for preflight caching
  • Implement additional security headers alongside CORS

Performance Optimization Strategies

Proper CORS and Nginx configuration can significantly impact your application's performance. Here are optimization strategies:

Static Asset Optimization

  • Serve static assets directly from Nginx with appropriate caching headers
  • Use CDN integration for global asset delivery
  • Implement proper cache-control headers for different asset types
  • Enable gzip compression for text-based assets

API Performance

  • Handle preflight requests efficiently at the Nginx level
  • Use appropriate max-age values to reduce preflight frequency
  • Implement API rate limiting alongside CORS
  • Consider using HTTP/2 for better multiplexing

Common CORS Misconfigurations and Fixes

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:

1. Allowing All Origins in Production

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']

2. Enabling Credentials with Wildcard Origins

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

3. Overly Broad Allowed Methods

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']

4. Permissive Allowed Headers

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']

5. Misconfigured CORS Middleware

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 Specific CORS Issues and Solutions

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:

Issue 1: CORS Middleware Not Working Despite Configuration

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);
})

Issue 2: Preflight OPTIONS Requests Failing

Problem: Browser preflight requests return "No 'Access-Control-Allow-Origin' header is present" error.

🔧 Debugging Steps:

  1. Test with curl: curl -I -X OPTIONS https://your-api.com/api/endpoint
  2. Check if CORS middleware is registered first: php artisan route:list
  3. Clear all caches: php artisan optimize:clear
  4. Restart PHP-FPM after configuration changes

Issue 3: Paths Configuration Not Working

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
],

Issue 4: Development vs Production Environment Issues

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',
],

Middleware Registration Problems

Laravel 12's new middleware registration system can be confusing. Here's how to properly register CORS middleware:

Method 1: Global Registration (Recommended)

// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    // Run CORS before everything else
    $middleware->prepend(\Illuminate\Http\Middleware\HandleCors::class);
})

Method 2: API Group Registration

// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    // Only for API routes
    $middleware->appendToGroup('api', \Illuminate\Http\Middleware\HandleCors::class);
})

Method 3: Conditional Registration

// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    // Only in non-production environments
    if (!app()->environment('production')) {
        $middleware->prepend(\Illuminate\Http\Middleware\HandleCors::class);
    }
})

Preflight Request Failures

Preflight requests are OPTIONS requests that browsers send before making certain cross-origin requests. Here's how to handle them properly:

Understanding Preflight Requests

Browsers send preflight requests when:

  • Request method is not GET, HEAD, or POST
  • Request includes custom headers
  • Content-Type is not application/x-www-form-urlencoded, multipart/form-data, or text/plain
  • Request includes credentials

Testing Preflight Requests

🔧 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

Development vs Production Configuration

Different environments require different CORS configurations. Here's how to handle this properly:

Environment-Specific CORS Configuration

// 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,
];

Using Environment Variables

// 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
]),

Advanced CORS Scenarios

Some applications require more complex CORS configurations. Understanding these advanced scenarios helps you build robust, scalable applications.

Multiple Subdomains

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.

Dynamic Origin Validation

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.

Third-Party Integrations

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.

Testing CORS Configuration

Proper testing ensures your CORS configuration works correctly across different scenarios. Here are testing strategies and tools:

Browser Developer 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.

Automated Testing

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.

Cross-Browser Testing

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.

Monitoring and Debugging

Effective monitoring helps you identify and resolve CORS issues quickly. Implement logging and monitoring for CORS-related events.

Logging CORS 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.

Error Tracking

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.

Frequently Asked Questions

What is CORS and why do I need it?

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.

How do I configure CORS in Laravel 12?

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.

Why is my CORS middleware not working in Laravel 12?

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.

What's the difference between simple and preflight requests?

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.

How do I test CORS configuration?

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

Should I configure CORS in Laravel or Nginx?

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.

Why are my CORS requests failing?

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.

How do I handle CORS for multiple environments?

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.

What's the correct middleware registration for Laravel 12?

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.

How do I debug CORS issues in Laravel 12?

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.

Can I use wildcard (*) for allowed origins?

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.

Can I disable CORS for development?

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.

How do I handle CORS with authentication?

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.

What are the performance implications of CORS?

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.

How do I handle CORS with Laravel Sanctum?

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.

What's the difference between allowed_origins and allowed_origins_patterns?

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.

How do I troubleshoot "No 'Access-Control-Allow-Origin' header" errors?

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.

Can I use CORS with Laravel Passport?

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.

How do I handle CORS for mobile applications?

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.