From 61d42d79f1181d25f4de5768051f1c80532c354f Mon Sep 17 00:00:00 2001 From: Yutaka Kurosaki Date: Sun, 30 Nov 2025 12:30:35 +0900 Subject: [PATCH] Enable language switching for guest users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - Move locale.update route outside auth middleware - Update LocaleController to support both authenticated and guest users - Guest users: Save locale preference to session only - Authenticated users: Save to both session and database - Add language switcher dropdown to header for all users - Display current language with globe icon - Show all 8 supported languages in dropdown - Highlight currently selected language with checkmark This allows non-logged-in users to change the interface language, improving accessibility for international visitors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- README.md | 97 +++++++++++++++++++ src/app/Http/Controllers/LocaleController.php | 13 ++- .../views/layouts/knowledge-base.blade.php | 45 +++++++++ src/routes/web.php | 4 +- 4 files changed, 153 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 948b543..0ccc0ce 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,20 @@ Markdown対応のナレッジベースアプリケーションです。Wiki風 - 👥 **ユーザー管理** - 管理者によるユーザーのCRUD操作 - 🔒 **認証** - Laravel Breezeによるログイン/登録機能 - 🎨 **シンタックスハイライト** - コードブロックの自動ハイライト +- 🌐 **多言語対応** - 8言語サポート(ユーザーごとに言語設定可能) + +## 対応言語 + +| 言語 | コード | +|------|--------| +| English | en | +| 日本語 | ja | +| Deutsch | de | +| Français | fr | +| Español | es | +| 简体中文 | zh-CN | +| 繁體中文 | zh-TW | +| 한국어 | ko | ## 技術スタック @@ -49,6 +63,7 @@ Markdown対応のナレッジベースアプリケーションです。Wiki風 │ │ ├── Livewire/ # Livewireコンポーネント │ │ ├── Models/ # Eloquentモデル │ │ └── Services/ # ビジネスロジック +│ ├── lang/ # 言語ファイル(i18n) │ ├── resources/views/ │ │ ├── layouts/ # レイアウト │ │ ├── livewire/ # Livewireビュー @@ -165,6 +180,62 @@ DocumentSeederを実行すると以下のドキュメントが作成されます ※ 既存のドキュメントがある場合、DocumentSeederはスキップされます。 +## 本番環境へのデプロイ + +### ⚠️ 重要: サブドメインを使用してください + +このアプリケーションは **サブドメイン** でのデプロイを推奨します。 + +``` +✅ 推奨: kb.example.com +❌ 非推奨: example.com/kb (サブディレクトリ) +``` + +**理由**: Livewire 3はサブディレクトリデプロイに完全対応していません。`/livewire/update` エンドポイントがサブディレクトリを考慮しないため、AJAX通信が失敗します。 + +### デプロイ手順 + +1. **サブドメインのDNS設定** + ``` + kb.example.com → サーバーIPアドレス + ``` + +2. **Webサーバー設定**(nginx例) + ```nginx + server { + listen 80; + server_name kb.example.com; + root /var/www/knowledge-base/src/public; + + index index.php; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + } + } + ``` + +3. **環境変数の設定** + ```env + APP_URL=https://kb.example.com + APP_ENV=production + APP_DEBUG=false + ``` + +4. **本番用の最適化** + ```bash + php artisan config:cache + php artisan route:cache + php artisan view:cache + php artisan optimize + ``` + ## よく使うコマンド ```bash @@ -181,6 +252,12 @@ docker exec kb_php npm [command] # コンテナに入る docker exec -it kb_php bash + +# キャッシュクリア +docker exec kb_php php artisan config:clear +docker exec kb_php php artisan route:clear +docker exec kb_php php artisan view:clear +docker exec kb_php php artisan cache:clear ``` ## 管理者機能 @@ -219,6 +296,15 @@ docker exec -it kb_php bash [[Laravel/Livewire/Components]] も確認してください。 ``` +## 言語設定 + +ユーザーは「プロフィール」ページから使用言語を変更できます。 + +1. 右上のユーザー名をクリック +2. 「プロフィール」を選択 +3. 「言語設定」セクションで言語を選択 +4. 「保存」をクリック + ## トラブルシューティング ### パーミッションエラー @@ -243,6 +329,17 @@ docker compose up -d `src/.env` の `DB_HOST` が `kb_mysql` になっているか確認してください。 +### Livewireのエラー(本番環境) + +「404 /livewire/update」エラーが出る場合は、サブディレクトリではなくサブドメインでデプロイしてください。 + +```bash +# キャッシュをクリア +php artisan config:clear +php artisan route:clear +php artisan cache:clear +``` + ## ライセンス MIT License diff --git a/src/app/Http/Controllers/LocaleController.php b/src/app/Http/Controllers/LocaleController.php index da9e42b..d3068cd 100644 --- a/src/app/Http/Controllers/LocaleController.php +++ b/src/app/Http/Controllers/LocaleController.php @@ -10,6 +10,7 @@ class LocaleController extends Controller { /** * Update the user's locale preference. + * Works for both authenticated and guest users. */ public function update(Request $request) { @@ -19,12 +20,14 @@ public function update(Request $request) $locale = $validated['locale']; - // Save to user record - Auth::user()->update(['locale' => $locale]); - - // Also save to session for immediate effect + // Save to session (works for both authenticated and guest users) $request->session()->put('locale', $locale); - return redirect()->route('profile.edit')->with('success', __('messages.settings.language_updated')); + // If authenticated, also save to user record for persistence + if (Auth::check()) { + Auth::user()->update(['locale' => $locale]); + } + + return redirect()->back()->with('success', __('messages.settings.language_updated')); } } diff --git a/src/resources/views/layouts/knowledge-base.blade.php b/src/resources/views/layouts/knowledge-base.blade.php index 523898f..42aeec1 100644 --- a/src/resources/views/layouts/knowledge-base.blade.php +++ b/src/resources/views/layouts/knowledge-base.blade.php @@ -59,6 +59,51 @@ class="inline-flex items-center px-3 py-2 border border-gray-300 shadow-sm text- + +
+ + +
+ @foreach($locales as $code => $name) +
+ @csrf + + +
+ @endforeach +
+
+ @auth
diff --git a/src/routes/web.php b/src/routes/web.php index 138ddcc..86afa5e 100644 --- a/src/routes/web.php +++ b/src/routes/web.php @@ -22,11 +22,13 @@ return view('dashboard'); })->middleware(['auth', 'verified'])->name('dashboard'); +// Locale switcher - available for all users (both authenticated and guest) +Route::post('/locale', [LocaleController::class, 'update'])->name('locale.update'); + Route::middleware('auth')->group(function () { Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); - Route::post('/locale', [LocaleController::class, 'update'])->name('locale.update'); }); // Admin routes