yaswanthgupta's avatar

Reverse Proxy + Laravel (React Starter Kit) Issue

My Setup

  • Laravel React Starter Kit hosted on IIS (Port 81)
  • Nginx running on Port 8000

Configuration Details

Nginx

  • A location block is configured with proxy_pass pointing to port 81

  • When a user visits, http://server_ip:8000/app1 it proxies to http://server_ip:81/app1

Vite - vite.config.js

base: '/app1/'

Laravel - bootstrap/app.php

->withMiddleware(function (Middleware  $middleware) {
$middleware->trustProxies(at: '*');

Laravel - .env

APP_URL=http://server_ip:8000/app1 ASSET_URL=http://server_ip:8000/app1

Issue

I am able to access the site via http://server_ip:8000/app1 but the URL automatically goes back to http://server_ip:8000/ . Now I cannot login not i cannot just refresh the browser because the app is in http://server_ip:8000/app1

I have also tried in multiple ways like proxying through IIS also (without Nginx). Here also, I face the same issue.

Kindly help me out !

0 likes
2 replies
LaryAI's avatar
Level 58

Certainly! Based on your setup and the problem description, here’s why it’s happening and how to address it:

Issue Explanation

When running a Laravel app behind a reverse proxy and setting a base path like /app1, it is common to encounter issues where URLs do not honor the subdirectory. This is because:

  • Laravel (and any React SPA served from Laravel) by default assumes the app is at the root /, unless told otherwise.
  • Vite's base config helps in generating frontend/static resource URLs, but Laravel route/redirect helpers also need to be made aware of the subdirectory.
  • If any redirect or asset generation on the backend ignores /app1, you'll get redirected to / instead.

How To Fix

1. Nginx Proxy Configuration

Make sure your location block properly strips the /app1 prefix before forwarding to IIS. Here’s the ideal setup:

location /app1/ {
    proxy_pass http://127.0.0.1:81/app1/;
    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;
}

If requests are proxied as /app1 to IIS, ensure IIS serves Laravel at that path, or strip /app1:

location /app1/ {
    rewrite ^/app1/(.*)$ /$1 break;
    proxy_pass http://127.0.0.1:81/;
    # headers...
}

Choose the approach that matches your physical/virtual directory setup in IIS.


2. Set Laravel’s Public Path and Route Prefixes

If your app is in a subdirectory:

  • Set Laravel's APP_URL and ASSET_URL in .env as you did:

    APP_URL=http://server_ip:8000/app1
    ASSET_URL=http://server_ip:8000/app1
    
  • For correct redirect and route generation, update your RouteServiceProvider (in app/Providers/RouteServiceProvider.php):

    public function boot()
    {
        // ...
        // Add this:
        \URL::forceRootUrl(config('app.url'));
    
        // If using HTTPS in production, uncomment:
        // \URL::forceScheme('https');
    
        parent::boot();
    }
    

3. Fix Session/Redirect URLs

If session or authentication redirects aren’t respecting /app1, add this middleware to force the base path in URLs.

Example middleware (app/Http/Middleware/ForceBasePath.php):

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\URL;

class ForceBasePath
{
    public function handle($request, Closure $next)
    {
        URL::forceRootUrl(config('app.url'));

        if (str_starts_with(config('app.url'), 'https://')) {
            URL::forceScheme('https');
        }

        return $next($request);
    }
}

Register it in app/Http/Kernel.php to web middleware group.


4. Vite Config

Your Vite config should look like:

export default defineConfig({
  base: '/app1/', // Correct!
  // ...
});

5. Clear Laravel Config Cache

After making changes:

php artisan config:cache
php artisan route:clear

6. Check .htaccess (if still using Apache/IIS URL rewrite)

If using IIS, ensure web.config is not rewriting URLs in a way that disrupts /app1 prefixes.


Summary

  • Proxy must handle /app1 prefix properly
  • Laravel’s APP_URL, ASSET_URL, and URL generator must include /app1
  • Ensure route and asset generation respect subdirectory
  • Clear caches after changes

Final Takeaway:
Everything that generates URLs (Laravel’s URL helpers, route() calls, asset() calls, and frontend Vite config) must be aware of the /app1 prefix. Most redirect issues come from the backend using the wrong root URL.


If you try all the above and still have issues, please provide:

  • Sample nginx.conf snippet
  • Details of IIS site setup (is Laravel in a virtual directory named app1?)
  • A sample of the Laravel-generated redirect URL that is wrong

This will allow for further debug!

yaswanthgupta's avatar

I have revised my setup. I am hosting the site in nginx using port 8001.

Here are my files. I will describe the issue at the end of the files.

nginx.conf file

.env file

APP_URL=http://server_ip:8000/APGBDOS
ASSET_URL=http://server_ip:8000/APGBDOS

vite.config.ts file

AppServiceProvider.php file boot method

    public function boot(): void
    {
        // If APP_URL is set in .env, force Laravel to use it as the root
        if (config('app.url')) {
            URL::forceRootUrl(config('app.url'));
        }

        // Handle X-Forwarded-Prefix header from nginx
        if ($prefix = request()->header('X-Forwarded-Prefix')) {
            // This ensures Laravel knows about the prefix
            request()->server->set('SCRIPT_NAME', $prefix . '/index.php');
        }

part of login.tsx file

import login from "@/routes/login";

    post(login.store.url(), {
      onFinish: () => reset("password")
    });

Issue:

As my AppServiceProvider.php file has URL::forceRootUrl(config('app.url'));, wayfinder is generating absolute urls instead of relative urls. Because of this, I get this error in console while submitting the login form (observe there is double http).

POST http://http//server_ip:8000/APGBDOS/login net::ERR_NAME_NOT_RESOLVED

If I remove URL::forceRootUrl(config('app.url')); in AppServiceProvider.php file making the wayfinder to generate relative paths. I get this error

404 Not Found nginx/1.28.0

For Reference:

part of resources\js\routes\login\index.ts file BEFORE adding URL::forceRootUrl(config('app.url')); in AppServiceProvider.php file

store.definition = {
    methods: ["post"],
    url: '/login',
} satisfies RouteDefinition<["post"]>

/**
* @see \Laravel\Fortify\Http\Controllers\AuthenticatedSessionController::store
 * @see vendor/laravel/fortify/src/Http/Controllers/AuthenticatedSessionController.php:58
 * @route '/login'
 */
store.url = (options?: RouteQueryOptions) => {
    return store.definition.url + queryParams(options)
}

part of resources\js\routes\login\index.ts file AFTER adding URL::forceRootUrl(config('app.url')); in AppServiceProvider.php file

store.definition = {
    methods: ["post"],
    url: '//http://server_ip:8000/APGBDOS/login',
} satisfies RouteDefinition<["post"]>

/**
* @see \Laravel\Fortify\Http\Controllers\AuthenticatedSessionController::store
 * @see vendor/laravel/fortify/src/Http/Controllers/AuthenticatedSessionController.php:58
 * @route '//http://server_ip:8000/APGBDOS/login'
 */
store.url = (options?: RouteQueryOptions) => {
    return store.definition.url + queryParams(options)
}

Please or to participate in this conversation.