Vue Router historyモードでページリロード時に404エラーが発生する問題の解決方法

Vue.js を使用して開発したアプリケーションを本番環境にデプロイした際、history モードを利用していると、ページをリロードしたときに 404 エラーが発生することがよくあります。これは、クライアントサイドルーティングで生成された URL に対して、サーバー側が対応する静的ファイルを返せないために起こります。以下では、Vue プロジェクトと Nginx の設定を調整することでこの問題を解決する手順を説明します。

原因の概要

vue-routerhistory モードは URL からハッシュ(#)を除去し、よりクリーンなパス形式(例: /dashboard)を実現します。しかし、この形式の URL は実際のファイルやディレクトリに対応していないため、ユーザーが直接アクセスしたりページをリロードしたりすると、Web サーバー(例: Nginx)は該当するリソースが存在しないと判断して 404 を返します。

解決手順

1. 環境変数の設定(.env.production

プロジェクトルートに .env.production ファイルを作成または編集し、アプリケーションのベースパスとパブリックパスを定義します。ここでは、アプリが /admin-panel というサブパスで配信されると仮定します。

VUE_APP_BASE_PATH=/admin-panel
PUBLIC_PATH=http://example.com/admin-panel

2. Vue Router のベースパス設定

src/router/index.js(または該当ファイル)で、ルーターの base オプションを環境変数に基づいて設定します。

import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(process.env.VUE_APP_BASE_PATH || '/'),
  routes: [...],
})

3. vue.config.js のパブリックパス設定

静的アセットの参照先を正しくするために、vue.config.js に以下の設定を追加します。

module.exports = {
  publicPath: process.env.NODE_ENV === 'production'
    ? process.env.PUBLIC_PATH
    : '/',
}

4. Nginx の設定

Nginx の設定ファイル(例: /etc/nginx/sites-available/default)で、対応する location ブロックを追加します。静的ファイルは /var/www/html/admin-panel に配置されていると仮定します。

location /admin-panel {
    alias /var/www/html/admin-panel;
    try_files $uri $uri/ /admin-panel/index.html;
}

try_files により、存在しないパスへのリクエストも index.html にフォールバックされ、Vue Router がクライアント側で適切にルーティングを処理できます。

5. ビルドとデプロイ

以下のコマンドで本番ビルドを実行し、生成された dist ディレクトリの内容を Nginx の対応ディレクトリにコピーします。

npm run build
# または、スクリプト名が異なる場合はそれに従う(例: npm run build:prod)

その後、Nginx の設定を検証して再読み込みします。

nginx -t
nginx -s reload

これにより、history モードを使用した Vue アプリケーションでも、ページリロード時に 404 エラーが発生しなくなります。

タグ: vue.js vue-router nginx SPA history mode

7月5日 17:43 投稿