Laravel 12 + Inertia.js(React)部署在子目录下自定义路由返回404 Not Found
我刚帮朋友踩过几乎一模一样的子目录部署坑,太懂你这种“默认路由正常、自定义路由全挂”的崩溃感了!其实就是几个关键配置没补全,我给你梳理下排查和解决的具体步骤:
1. 给Laravel后端路由统一加前缀
你只在前端Link里加了/app前缀,但Laravel的后端路由本身还没对应上这个前缀,自然会找不到路由返回404。有两种省心的处理方式:
方式一:在web.php里包裹路由组
把所有自定义Inertia路由都放到prefix('app')的分组里,比如:
// routes/web.php Route::prefix('app')->group(function () { // 你的所有自定义Inertia路由都放这里 Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard'); Route::get('/profile', [ProfileController::class, 'show'])->name('profile'); // 其他自定义路由... });
方式二:全局路由加前缀(一劳永逸)
如果不想一个个包裹路由组,直接在RouteServiceProvider里给所有web路由加全局前缀:
// app/Providers/RouteServiceProvider.php public function boot(): void { $this->routes(function () { Route::middleware('web') ->prefix('app') // 新增这一行,全局添加/app前缀 ->namespace($this->namespace) ->group(base_path('routes/web.php')); }); }
这样不管你在web.php里写什么路由,都会自动带上/app前缀,和你访问的URL完全匹配。
2. 补全Inertia的全局URL前缀配置
你改了app.tsx的Link,但可能没配置Inertia的全局URL前缀,导致Inertia发起的异步请求还是不带/app。在resources/js/app.tsx的Inertia初始化代码里,加上URL前缀的处理:
import { createInertiaApp } from '@inertiajs/react'; import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; import { createRoot } from 'react-dom/client'; createInertiaApp({ resolve: (name) => resolvePageComponent(`./Pages/${name}.tsx`, import.meta.glob('./Pages/**/*.tsx')), setup({ el, App, props }) { createRoot(el).render(<App {...props} />); }, // 关键:给所有Inertia请求自动追加/app前缀 url: (url) => `/app${url}`, });
这样不管是Inertia的visit方法还是<Link>组件,都会自动带上/app前缀,不用手动在每个地方加。
3. 确认cPanel的子目录文档根配置
这是很多人容易忽略的细节:你把Laravel项目放在/app子目录,但cPanel里这个子目录的文档根必须指向/app/public,而不是/app本身。如果文档根设成了/app,服务器会直接访问Laravel根目录,而不是public入口文件,路由肯定会乱套。
你可以登录cPanel,进入「文件管理器」,找到app文件夹,右键点击public文件夹,确认它是不是被设为了这个子目录的文档根。如果不是,去「域名」管理模块调整一下即可。
4. 清理Laravel缓存(必做步骤)
你改了.env的APP_URL,也调整了路由配置,一定要在服务器上运行这几个命令清理缓存,否则Laravel会一直用旧的缓存配置:
php artisan config:clear php artisan route:clear php artisan cache:clear
别嫌麻烦,很多时候配置不生效就是因为没清缓存。
5. 再核对下.htaccess的RewriteBase
你现在的.htaccess里RewriteBase /app/是对的,但要确认服务器上的文件路径是否匹配:你的Laravel项目是不是放在public_html/app下,public文件夹在public_html/app/public?如果路径是对的,这个配置就没问题,不用修改。
按照这个顺序排查,先从后端路由前缀开始——这是90%子目录部署404的根源,前端改了但后端路由没跟上,请求到Laravel那里找不到对应的路由,自然返回404。
内容来源于stack exchange

