--- title: Reactで直接URLをたたくと404になる時の対応 tags: React react-router-dom author: yakipudding slide: false --- # Reactで直接URLをたたくと404になる時の対応 ## 前提:react-router-domでルーティングしてる ```html:index.html
``` ```js:index.js import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; ReactDOM.render(, document.getElementById('root')); ``` ```js:App.js import React, { Component } from 'react' import { BrowserRouter, Switch, Route } from 'react-router-dom' class App extends Component { render() { return (
); } } ``` ## 状況:直接URL叩くと404になる - うまくいくケース - `https://hogeapp.com/`にアクセス → HomeComponentが表示される - /Fugaのリンクを踏む - `https://hogeapp.com/Fuga`に遷移 → FugaComponentが表示される - うまくいかないケース - `https://hogeapp.com/Fuga`が表示された後リロードする → 404ページが表示される - ブラウザで`https://hogeapp.com/Fuga`を直接叩く → 404ページが表示される ## 原因:SPA構成だと直リンクはリソースがないから死ぬ - リソースが存在しないと直接URLにアクセスしても404になるから - うまくいった時の流れ - `https://hogeapp.com/`にアクセス - `index.html`を読み込む - react-router-domのルーティングによりHomeComponentが表示される - /Fugaのリンクを踏む - react-router-domのルーティングによりFugaComponentが表示される - うまくいかないときの流れ - `https://hogeapp.com/Fuga`のURLに直接アクセス - /Fugaリソースを探そうとするが、見つからない - 404ページ表示 ## 対策:サーバー側の設定でリライト設定をする - Webサーバーの設定で`index.html`へのリライト指定をする - 例えばFirebase Hostingなら`firebase.json`ファイルの hosting 内で rewrites セクションを定義できる - 参考:https://firebase.google.com/docs/hosting/full-config?hl=ja#rewrites ```json:firebase.json { "hosting": { "rewrites": [ { "source": "**", "destination": "/index.html" } ] } } ``` - 上記のように全要素index.htmlに飛ばすならreact-router-domのルーティングで404コンポーネントを返却するようにする - もともとWebサーバー側で設定していた404.htmlは機能しなくなるので ```js:App.js import React, { Component } from 'react' import { BrowserRouter, Switch, Route } from 'react-router-dom' class App extends Component { render() { return (
); } } ``` ## 参考 - ここの回答 - https://teratail.com/questions/26245