この記事について
1年ほど前からReactを使ったホームページの開発にはまっており、最近になってやっとルーティングのためにReact Router
を導入しました。React Router
を利用したら簡単にルーティングが実装できたのでとても感動しました。
しかし、デプロイ後に直リンクで下層のページにアクセスしようとしたり、ローディングで再読み込みをしようとしたりすると、404エラーになってしまう問題に直面しました。本稿は、この問題の解決策(めちゃくちゃ簡単ですが)を説明するものです。
注意
Qiitaの記事を書くのは初めてで、開発の知識も弱々なのでいろいろと間違っているかもしれません。その時は温かい気持ちでご指摘ください。
そもそも何が起きているのか
はじめに説明した問題を具体例を通して説明します。例えば、React Router
を導入したReact
アプリをhttps://example.com
から配信し、https://example.com
のページ上にhttps://example.com/page
へのリンクが貼られているとします。つまり、
const router = createBrowserRouter([
{
path: "/",
element: <Top />,
},
{
path: "/page",
element: <Page />,
},
])
こんな感じでルーティングされているとします。
このときhttps://example.com
からhttps://example.com/page
への遷移はうまく行きますが、https://example.com/page
に直リンクでアクセスしたり、再読み込みをしたりすると404エラーが発生します。
これは実はReact Router
側の問題ではなく、サーバー側の問題です。どういうことかと言うと、例えばNGINX
などではhttps://example.com
にリクエストがあった場合は、index.html
を返すという風に設定がなされていると思います。この状況下では、https://example.com/page
にアクセスがあったときの設定がNGINX
に適切になされていないがために404になるのです。
解決策
解決策は簡単です。どこにリクエストがあろうが404になった場合はindex.html
を返すようにNGINX
側で設定してやれば良いのです。それを可能にする設定は次です。
location / {
index index.html;
try_files $uri /index.html;
}
try_files $uri /index.html
とは何かという話ですが、これはいろいろとHTML
ファイルを探して、見つからなかったらindex.html
を返すという設定です。詳しくはこちらをご参照ください。
これで意図しない404エラーは発生しなくなると思います。一方で、エラーページはNGINX
側では配信されなくなるので、React Router
で設定する必要があります。ここには注意するようにしてください。