Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tighten/ziggy/llms.txt

Use this file to discover all available pages before exploring further.

If Ziggy’s route() helper generates URLs with an http scheme when your application uses https, the issue is likely related to TLS/SSL termination or proxy configuration.

The Problem

When your application is behind a load balancer, proxy, or uses TLS/SSL termination, Laravel may not correctly detect that the original request used HTTPS. This causes Ziggy to generate URLs with the wrong scheme:
// Expected:
route('posts.show', 1); // 'https://myapp.com/posts/1'

// But getting:
route('posts.show', 1); // 'http://myapp.com/posts/1'

Common Scenarios

This issue typically occurs when:
  • Using a reverse proxy (like Nginx or Apache) that handles SSL/TLS
  • Behind a load balancer (AWS ELB, Cloudflare, etc.)
  • Hosted on platforms like Heroku, Laravel Forge, or AWS Elastic Beanstalk
  • Using TLS/SSL termination

Solution: Configure Trusted Proxies

Laravel includes a middleware for configuring trusted proxies. Follow these steps to fix the scheme detection:
1

Locate the TrustProxies middleware

The middleware is located at:
app/Http/Middleware/TrustProxies.php
If it doesn’t exist, you can create it or publish it from Laravel’s middleware.
2

Configure the proxies property

Set the $proxies property to trust your proxy or load balancer. For most cases, you can trust all proxies:
<?php

namespace App\Http\Middleware;

use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array<int, string>|string|null
     */
    protected $proxies = '*'; // Trust all proxies

    /**
     * The headers that should be used to detect proxies.
     *
     * @var int
     */
    protected $headers =
        Request::HEADER_X_FORWARDED_FOR |
        Request::HEADER_X_FORWARDED_HOST |
        Request::HEADER_X_FORWARDED_PORT |
        Request::HEADER_X_FORWARDED_PROTO |
        Request::HEADER_X_FORWARDED_AWS_ELB;
}
3

Verify middleware is registered

Ensure the middleware is registered in your bootstrap/app.php or app/Http/Kernel.php (depending on your Laravel version):Laravel 11+:
// bootstrap/app.php

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustProxies(at: '*');
})
Laravel 10 and earlier:
// app/Http/Kernel.php

protected $middleware = [
    // ...
    \App\Http\Middleware\TrustProxies::class,
    // ...
];
4

Clear config cache

After making changes, clear your configuration cache:
php artisan config:clear
php artisan cache:clear
5

Test the fix

Generate a URL and verify it uses HTTPS:
route('posts.show', 1);
// Should now return: 'https://myapp.com/posts/1'

Platform-Specific Configuration

AWS Elastic Load Balancer

For AWS ELB, ensure the HEADER_X_FORWARDED_AWS_ELB header is included:
protected $headers =
    Request::HEADER_X_FORWARDED_FOR |
    Request::HEADER_X_FORWARDED_HOST |
    Request::HEADER_X_FORWARDED_PORT |
    Request::HEADER_X_FORWARDED_PROTO |
    Request::HEADER_X_FORWARDED_AWS_ELB;

Cloudflare

Cloudflare adds its own headers. Trust Cloudflare’s IP ranges:
protected $proxies = [
    '173.245.48.0/20',
    '103.21.244.0/22',
    '103.22.200.0/22',
    '103.31.4.0/22',
    '141.101.64.0/18',
    '108.162.192.0/18',
    '190.93.240.0/20',
    '188.114.96.0/20',
    '197.234.240.0/22',
    '198.41.128.0/17',
    '162.158.0.0/15',
    '104.16.0.0/13',
    '104.24.0.0/14',
    '172.64.0.0/13',
    '131.0.72.0/22',
];
Or use environment variables:
protected $proxies = explode(',', env('TRUSTED_PROXIES', ''));

Heroku

Heroku handles SSL termination. Trust all proxies:
protected $proxies = '*';

Laravel Forge with Nginx

Forge’s default Nginx configuration forwards the correct headers. Simply trust all proxies:
protected $proxies = '*';

Environment-Specific Settings

For different configurations per environment, use environment variables:
// app/Http/Middleware/TrustProxies.php

protected $proxies;

public function __construct()
{
    $this->proxies = env('TRUSTED_PROXIES', '*');
}
Then in your .env files:
# .env.local
TRUSTED_PROXIES=*

# .env.production
TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16

Verifying APP_URL Configuration

Ensure your APP_URL in .env uses HTTPS:
APP_URL=https://myapp.com
This affects URL generation throughout Laravel, including Ziggy.

Troubleshooting

Still Getting HTTP URLs?

Verify that proxy headers are being sent. Add temporary debugging:
// In a controller or route
return [
    'scheme' => request()->getScheme(),
    'secure' => request()->secure(),
    'headers' => [
        'X-Forwarded-Proto' => request()->header('X-Forwarded-Proto'),
        'X-Forwarded-Port' => request()->header('X-Forwarded-Port'),
    ],
];
Expected output:
{
    "scheme": "https",
    "secure": true,
    "headers": {
        "X-Forwarded-Proto": "https",
        "X-Forwarded-Port": "443"
    }
}
If your proxy isn’t sending the correct headers, configure it to do so.Nginx example:
location / {
    proxy_pass http://localhost:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Port $server_port;
}
Apache example:
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
As a last resort, force HTTPS in your AppServiceProvider:
// app/Providers/AppServiceProvider.php

use Illuminate\Support\Facades\URL;

public function boot()
{
    if (app()->environment('production')) {
        URL::forceScheme('https');
    }
}
Note: This should be a last resort. Properly configuring trusted proxies is the recommended approach.

Mixed Content Warnings

If you’re getting mixed content warnings in the browser:
  1. Ensure all assets use HTTPS
  2. Check that ASSET_URL in .env uses HTTPS:
ASSET_URL=https://myapp.com
  1. Use protocol-relative URLs or Laravel’s secure_asset() helper

Testing Locally with HTTPS

To test HTTPS locally:
  1. Use Laravel Valet (macOS):
    valet secure myapp
    
  2. Use Laravel Herd (macOS/Windows): HTTPS is enabled by default
  3. Use Laragon (Windows): Enable SSL in the Laragon menu

Additional Resources