如何在React+Laravel Inertia中结合mcamara实现后端本地化
实现方案:Laravel(mcamara) + Inertia + React 后端驱动本地化
核心思路
既然允许页面重载,完全可以复用mcamara的路由本地化逻辑,由后端处理语言切换和翻译数据加载,再通过Inertia将翻译数据传递给React前端,前端直接调用这些数据完成文本渲染,全程依赖后端驱动,无需前端动态切换逻辑。
步骤1:配置mcamara路由与语言切换
保持你原有mcamara的配置不变,确保路由前缀包含语言代码(如/en/home、/zh/home),同时添加语言切换路由:
// routes/web.php Route::get('lang/{locale}', function ($locale) { if (!in_array($locale, config('app.locales'))) { abort(400); } session()->put('locale', $locale); return redirect()->back(); })->name('lang.switch');
在AppServiceProvider中设置当前请求的语言:
// app/Providers/AppServiceProvider.php public function boot() { if (session()->has('locale')) { app()->setLocale(session('locale')); } }
步骤2:通过Inertia共享翻译数据
在HandleInertiaRequests中间件中,将当前语言的翻译文件内容共享给前端:
// app/Http/Middleware/HandleInertiaRequests.php use Illuminate\Support\Facades\File; public function share(Request $request) { return array_merge(parent::share($request), [ 'locale' => app()->getLocale(), 'translations' => function () { $locale = app()->getLocale(); $translations = []; $files = File::allFiles(resource_path("lang/{$locale}")); foreach ($files as $file) { $key = str_replace('.php', '', $file->getFilename()); $translations[$key] = require $file->getPathname(); } return $translations; }, ]); }
步骤3:React前端实现翻译函数
创建一个轻量的翻译工具函数,解析Inertia传递的翻译数据:
// src/utils/trans.js export function trans(key, replacements = {}) { const translations = window.Inertia.page.props.translations; const keys = key.split('.'); let value = translations; // 逐层解析翻译键名,如'auth.failed' for (const k of keys) { value = value?.[k]; if (!value) return key; // 找不到翻译时返回原键名 } // 替换占位符,如'Hello :name' Object.entries(replacements).forEach(([placeholder, replacement]) => { value = value.replace(`:${placeholder}`, replacement); }); return value; }
在组件中直接调用:
import { trans } from '../utils/trans'; function Welcome() { return ( <div> <h1>{trans('welcome.title')}</h1> <p>{trans('welcome.message', { name: 'Lana' })}</p> </div> ); }
步骤4:语言切换组件
因为允许页面重载,直接通过链接指向后端语言切换路由即可:
function LanguageSwitcher() { const locales = ['en', 'zh']; const currentLocale = window.Inertia.page.props.locale; return ( <div className="language-switcher"> {locales.map(locale => ( <a key={locale} href={`/lang/${locale}`} className={currentLocale === locale ? 'active' : ''} > {locale.toUpperCase()} </a> ))} </div> ); }
额外优化建议
- 缓存翻译数据:后端可将加载的翻译数组缓存,减少每次请求的文件读取操作
- 路由生成规范:后端生成语言切换URL时,使用
route('lang.switch', ['locale' => $locale])确保路径正确 - 非法语言拦截:在语言切换路由中严格校验传入的locale是否在配置允许范围内
内容的提问来源于stack exchange,提问作者Lana Hanna
相关产品推荐
相关产品推荐

