You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Laravel Mix+VueRouter历史模式Nginx下子级URL刷新失效求助

Fixing Vue Router History Mode Sub-Route Refresh Issues on Nginx (Laravel Mix)

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

火山引擎 最新活动