In simple terms, APP_URL is more like Laravel's "default address", not something that automatically changes every URL generated during a normal web request.
When you're using ngrok, Laravel should ideally detect the ngrok URL from the incoming request. If it's still generating localhost URLs, that usually means the proxy/headers aren't being passed correctly.
I'd use ASSET_URL only if I specifically want assets to come from a different URL (like a CDN). It works, but it feels more like a workaround in this case.
URL::forceRootUrl() also works, but it's a global override and I'd keep it as a last resort.
So for ngrok or a real setup behind a proxy, my preference would be:
Configure the proxy correctly so Laravel sees the real URL. Use APP_URL as the application's canonical URL. Only use ASSET_URL or forceRootUrl() if Laravel genuinely can't determine the correct URL on its own.
In other words: fix the proxy configuration first, use overrides only when necessary.
Thanks for the reply, Kapil! I applied the TrustProxies fix and it worked perfectly. I totally get the logic behind the proxy and headers now. I can tell you’ve been through this in the wild (and probably saved a few deploys from a quiet panic 😅). A good dev always prefers fixing the root cause over applying a fancy band-aid. Really appreciate the help!
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.