NGrok and Laravel

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company
# Bridging the Gap: Solving Ngrok URL Mismatches in Local Laravel Development Deploying a local Laravel application to the internet using tools like ngrok is an incredibly useful step for testing, demonstrating features, or getting early feedback. However, as you’ve discovered, bridging the gap between your local development environment (like Laragon/Apache) and the public tunnel provided by ngrok often introduces frustrating issues, particularly concerning asset linking and routing. This post dives deep into why this happens and provides a robust, developer-centric solution to ensure your Laravel application correctly serves content through the ngrok tunnel. ## The Root of the Problem: Local vs. Public Context The core issue stems from how Laravel is configured by default. When you develop locally, Laravel assumes it is running on `http://localhost` or `site.dev`. Any resource requests—whether for CSS files, images, or route generation—are based on this local context. When you run `ngrok http -host-header=rewrite site.dev:80`, ngrok creates a secure tunnel that maps an external address (e.g., `http://xxxxxx.ngrok.io`) to your local server. However, the *application itself* still references its internal development domain (`site.dev`), leading to broken links and incorrect routing results when accessed via the public ngrok URL. ## The Solution: Setting the Application Base URL The correct approach is not to rely on low-level Apache configuration files (like `httpd.conf`) for application routing, but rather to inform the Laravel framework itself what its public base URL is. This ensures that all generated URLs and asset paths are relative to the external tunnel. We need to explicitly tell Laravel what the public domain is so it can generate correct absolute links. ### Step 1: Configure the Environment Variables The most critical step is setting the application's base URL within your environment configuration. This allows Laravel’s helpers (like `asset()` or route generation) to prepend the ngrok address instead of `site.dev`. In your `.env` file, you should define the public URL: ```dotenv APP_URL=http://number.ngrok.io ``` Replace `number.ngrok.io` with the actual dynamic address provided by your ngrok session. This variable acts as the single source of truth for all external references in your application. ### Step 2: Verifying Application Configuration While setting `APP_URL` in `.env` is usually sufficient, it’s good practice to verify how Laravel interprets this within its core configuration. For modern Laravel applications, these settings are managed by the framework's conventions, which aligns with best practices outlined by teams working on frameworks like those found at [laravelcompany.com](https://laravelcompany.com). If you were manually overriding paths, you might check `config/app.php` to ensure no conflicting base URLs are defined, though typically, environment variables take precedence. ## Resolving Asset and Routing Issues Once you have set the `APP_URL`, Laravel should automatically adjust its behavior. ### Fixing Asset Linking (CSS/Images) If your assets were linking to `site.dev/css/app.css`, they will now correctly resolve to `http://number.ngrok.io/css/app.css`. Ensure you are using Laravel's built-in asset helpers: **Incorrect (Local Context):** ```html ``` **Correct (Using Blade Helpers):** ```html ``` ### Fixing Routing The same principle applies to route generation. When you use `route('ngo')`, Laravel will now prepend the configured `APP_URL` to generate the correct external link: **Incorrect (Local Context):** ```php return site.dev . '/ngo'; // Or using route() without base setup ``` **Correct (Using Route Helper with Base URL set):** ```php // Assuming APP_URL is set in .env return route('ngo'); // Laravel will generate: http://number.ngrok.io/ngo ``` ## Conclusion Dealing with local development tunnels requires shifting focus from low-level server configuration to application-level configuration. By correctly setting the `APP_URL` in your environment variables, you empower Laravel to manage all external references automatically. This method is cleaner, more resilient, and adheres better to the principles of building scalable applications, which is a fundamental concept when developing with frameworks like Laravel. Use this approach to ensure your local testing seamlessly translates into a publicly accessible demonstration.