react + react routerでアプリを作成して、ビルド後にApacheで公開するとルーティングがうまくいかずに404が発生することがあります。
開発時にwebpack-dev-serverなどを利用してデバックしていると気が付きませんが、ビルド後のbuild.jsをwebサーバー(Apache)にアップして確認するとページリロード時などに404が発生します。
シングルページアプリケーション(SPA)なのでwebサーバの設定が必要です。
404の原因
下記のようなURLがあるとします。
https://test.jp/profile
index.html(reactトップ)からlink toでprofileに移動するとreact routerが機能してindex.htmlのページ内容をprofileのページに書き換えます。(SPA)
しかし、URLが「https://test.jp/profile」の時にブラウザをリロードすると、
ブラウザがApacheに「https://test.jp/profile」のリクエストを投げます。
Apacheはドキュメントルート以下の(/var/www/htmlなど)のprofileというディレクトリを探します。
SPAで作成されたreactにはprofileとか実際のディレクリやファイルは存在しないはずです。
当然ページが見つからないので404を返します。not foundです。
react routerを機能させるにはindex.html(reactトップ)にhttps://test.jp/profileのリクエストを投げる必要があります。
httpd.confの設定
httpd.confを編集して.htaccessを使用できるように設定します。
<Directory />
AllowOverride none
</Directory>
AllowOverrideをAllに変更します。
<Directory />
AllowOverride All
</Directory>
各オプションはの意味は下記です。
- None
- .htaccessを無効にします
- All
- .htaccessで指定した全ディレクティブの使用を許可します。
- AuthConfig
- 認証に関するディレクティブを許可します。
- Limit
- ホスト名やIPアドレスによるアクセス制御を許可します。
- FileInfo
- ディレクトリ表示の設定を許可します。mod_rewriteはこの設定になります
- Indexes
- ディレクトリインデックスに関するディレクティブの使用を許可します。
- Options
- Options指定子で設定する機能を許可します。
.htaccessならFileInfoでいけるかもですが、私はいつもAllにしています。
セキュリティとか気になるならFileInfoで試してください。
あと設定するディレクトリも「Directory /」で全て許可していますが、
「Directory “/subdir”」などで、特定のディレクトリのみ指定することもできます。
リダイレクト設定
Apacheに来たリクエストをindex.html(reactトップ)に投げれば解決です。
リダイレクトには.htaccessを使用します。
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html [QSA,L]
上記の設定を書き込んだ.htaccessをApacheのドキュメントルートに設置します。
※mod_rewriteが利用できることが前提です。
解説
RewriteEngine On
リライトを有効にします。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCondでルールの適用条件を指定します。
!-fは%{REQUEST_FILENAME}のファイルが存在しない場合。
!-dは%{REQUEST_FILENAME}のディレクトリが存在しない場合。
RewriteRule ^ index.html [QSA,L]
RewriteCondが全てtrueならRewriteRuleでindex.htmlにリダイレクトします。
[QSA]はクエリストリング(?var=1)などを引き継ぐ。
[L]は処理はここで終了。
まとめ
上記の設定を.htaccessにするとディレクトリやファイルが存在しないときはindex.htmlにリダイレクトされます。
URLは変わりませんので、react-routerが機能して意図したページが表示されます。
reactなどSPAのアプリをルーティングする際はApacheの設定が必要になります。