Laravel Mix+VueRouter历史模式Nginx下子级URL刷新失效求助
Hey there! I’ve run into this exact issue a few times with Laravel Mix and Vue Router—let’s break down why this is happening and how to fix it.
Why the Sub-Route Refresh Breaks
When you switch to history mode, Vue Router handles all routing client-side, but when you refresh a sub-route like /pages/1, Nginx tries to find a physical file or directory at /pages/1 in your Laravel project’s public folder first. Since that doesn’t exist, your current try_files rule should fall back to /index.html, but there are a couple of common gaps that prevent this from working correctly.
Step 1: Verify Nginx Root Directory
First, double-check that your Nginx server block is pointing directly to your Laravel project’s public folder—this is critical. Your server block should look something like this:
server { listen 80; server_name your-domain.com; root /path/to/your/laravel-project/public; # This must point to public! index index.html index.php; # ... rest of your config }
Step 2: Update Nginx Location Rule
Modify your location / block to include the query string (helps preserve any URL parameters) and ensure it properly falls back to index.html. Here’s the corrected rule:
location / { try_files $uri $uri/ /index.html?$query_string; }
If you have API routes handled by Laravel, add a separate location block for /api to let Laravel process those:
location /api { try_files $uri $uri/ /index.php?$query_string; } location / { try_files $uri $uri/ /index.html?$query_string; }
Step 3: Add a Catch-All Route in Laravel
If your Laravel backend has routes that might conflict with your Vue routes (or if you’re serving the Vue app through Laravel’s views), add a catch-all route at the end of your routes/web.php file. This tells Laravel to pass all unmatched routes to your Vue app’s entry point:
// routes/web.php // ... your existing Laravel routes (API, admin, etc.) // Catch-all for Vue Router routes Route::get('/{any}', function () { return view('welcome'); // Or your Vue app's blade view })->where('any', '.*');
Step 4: Reload Nginx
After making these changes, reload Nginx to apply the new configuration:
sudo nginx -s reload
Bonus: Check Vue Router Base Path
If your app is deployed in a subdirectory (e.g., your-domain.com/app/), make sure you set the base option in Vue Router:
const router = new VueRouter({ mode: 'history', base: '/app/', // Match your subdirectory path routes: [/* your routes */] });
That should fix the refresh issue for sub-routes—now when you hit /pages/1 or /foo/bar/boo and refresh, Nginx will correctly serve index.html, and Vue Router will take over and load the right client-side route.
内容的提问来源于stack exchange,提问作者bernhardh




