Reactで直接URLをたたくと404になる時の対応
前提:react-router-domでルーティングしてる
index.html
<html>
<body>
<div id="root"></div>
</body>
</html>
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
App.js
import React, { Component } from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<Switch>
<Route exact path='/' component={HogeComponent} />
<Route exact path='/Fuga' component={FugaComponent} />
</Switch>
</div>
</BrowserRouter>
);
}
}
状況:直接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 セクションを定義できる
firebase.json
{
"hosting": {
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
- 上記のように全要素index.htmlに飛ばすならreact-router-domのルーティングで404コンポーネントを返却するようにする
- もともとWebサーバー側で設定していた404.htmlは機能しなくなるので
App.js
import React, { Component } from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<Switch>
<Route exact path='/' component={HogeComponent} />
<Route exact path='/Fuga' component={FugaComponent} />
<Route component={NotFound} />
</Switch>
</div>
</BrowserRouter>
);
}
}