Laravel+Voyager本地化后前端路由NotFoundHttpException问题解决
解决Laravel + Voyager本地化路由NotFoundHttpException问题
嘿,我来帮你搞定这个问题!结合我用Laravel和Voyager做本地化的实战经验,咱们一步步排查解决:
1. 先配置Laravel基础本地化设置
首先确保你的config/app.php里已经正确设置了支持的语言、默认语言和 fallback 语言:
// config/app.php 'locale' => 'en', // 默认语言 'fallback_locale' => 'en', // 当目标语言无内容时 fallback 的语言 'available_locales' => ['en', 'zh-CN'], // 自定义数组,列出你支持的所有语言代码
2. 重构前端路由,添加本地化前缀
把所有需要本地化的前端路由包裹在带{locale}前缀的路由组里,同时添加参数验证和中间件:
// routes/web.php // 先注册本地化路由组 Route::group([ 'prefix' => '{locale}', 'where' => ['locale' => '[a-zA-Z]{2}(-[a-zA-Z]{2})?'], // 适配 en、zh-CN 这类格式 'middleware' => 'setlocale' // 后面会创建这个中间件 ], function () { // 你的前端路由都放这里 Route::get('/', 'HomeController@index')->name('home'); Route::get('/articles/{slug}', 'ArticleController@show')->name('article.show'); // 其他路由... }); // 处理根路径跳转,自动跳转到默认语言的路由 Route::get('/', function () { return redirect()->route('home', ['locale' => app()->getLocale()]); });
3. 创建并注册本地化中间件
这个中间件用来根据路由参数自动切换应用的语言:
- 生成中间件:
php artisan make:middleware SetLocale
- 修改中间件逻辑:
// app/Http/Middleware/SetLocale.php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class SetLocale { public function handle(Request $request, Closure $next) { // 检查路由参数里的locale是否在支持列表中 if (in_array($request->locale, config('app.available_locales'))) { app()->setLocale($request->locale); } return $next($request); } }
- 把中间件注册到
app/Http/Kernel.php的web中间件组里:
// app/Http/Kernel.php protected $middlewareGroups = [ 'web' => [ // ... 其他中间件 \App\Http\Middleware\SetLocale::class, ], ];
4. 配置Voyager支持目标语言
确保Voyager的配置文件里已经添加了你要支持的语言,这样后台的翻译功能才能正常关联:
// config/voyager.php 'locales' => [ 'en' => 'English', 'zh-CN' => '简体中文', ],
5. 确保模型使用Voyager的Translatable Trait
你的内容模型(比如Article、Page)需要使用Voyager提供的Translatable trait,这样才能自动从translations表获取对应语言的内容:
// app/Models/Article.php namespace App\Models; use Illuminate\Database\Eloquent\Model; use TCG\Voyager\Traits\Translatable; class Article extends Model { use Translatable; // 列出需要本地化的字段(和你在Voyager后台设置的翻译字段一致) protected $translatable = ['title', 'content', 'slug']; }
6. 生成路由链接时传递locale参数
在视图或控制器里生成路由链接时,一定要带上locale参数,比如:
<!-- 视图里的链接 --> <a href="{{ route('home', ['locale' => app()->getLocale()]) }}">首页</a> <a href="{{ route('article.show', ['locale' => app()->getLocale(), 'slug' => $article->slug]) }}">查看文章</a>
常见问题排查
如果还是出现NotFound错误,检查这几点:
- 访问的URL是否符合路由规则(比如
/en或/zh-CN开头) - 路由参数的正则表达式是否覆盖了你使用的语言代码(比如支持带地区的代码就用
[a-zA-Z]{2}(-[a-zA-Z]{2})?) - 有没有重复的路由定义(比如未本地化的路由和本地化路由冲突)
- 中间件是否正确注册,有没有生效
内容的提问来源于stack exchange,提问作者Nahapet
相关产品推荐
相关产品推荐

