My code is using React-router-dom. It works on gh-pages with all navigation within the page. However, accessing by adding /blog to the url or refreshing the /blog page returns 404 not found. The app is structured like this:
App.js
function App() {
return (
<div className="App" >
<header className="App-header" width="100%" >
<BrowserRouter basename="/">
<Switch>
<Route component={Main} exact path="/" />
<Route component={Blog} exact path="/blog" />
</Switch>
</BrowserRouter>
</header>
</div>
);
}
export default App;
Blog.js:
function Blog() {
return (
<div className="App" >
<header className="App-header" width="100%" >
<div id="home" width="100%">
<BrowserRouter id="blog">
<div>
<Route component={AllPosts} exact path="/blog/" />
<Route component={OnePost} exact path="/blog/:slug" />
</div>
</BrowserRouter>
<SidebarIfBrowser />
</div>
</header>
</div>
);
}
export default Blog;
Do I miss something essential?
CodePudding user response:
The issue looks to be about how you are using nested routes.
First in App.js
remove the exact because you don't want it to be exact
// App.js
<Switch>
<Route component={Main} exact path="/" />
<Route component={Blog} path="/blog" />
</Switch>
Now in your Blog.js
there are a few edits you need to make. First is to replace your BrowserRouter
with Switch
. You only want to have 1 BrowserRouter
in your entire app and it should be in the high level which is what you have in your App.js
.
Then you want to change the paths
in your Routes. You dont need to include /blog/
in them since they are nested routes within the /blog
route from your App.js
Technically what you have before would of been /blog/blog
// Blog.js
function Blog() {
return (
<div className="App" >
<header className="App-header" width="100%" >
<div id="home" width="100%">
<Switch>
<div>
<Route component={AllPosts} exact path="/" />
<Route component={OnePost} exact path="/:slug" />
</div>
</Switch>
<SidebarIfBrowser />
</div>
</header>
</div>
);
}
export default Blog;
note this only works for react-router v5 and if you are using v6 then there are some other changes you would need
CodePudding user response:
This happens because you're making a GET request on the server for a non existing route. You can fix this by following the steps bellow:
1. Point the home page in your package.json
{
...
"homepage": ".",
...
}
2. Create a .htaccess file and place it in the root directory of your app
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.
RewriteRule ^(.*)$ https://yourdomain.com/$1 [R=301,L]
#RewriteCond %{THE_REQUEST} ^GET.*index\.html [NC]
#RewriteRule (.*?)index\.html/*(.*) /$1$2 [R=301,NE,L]
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
NOTE: This is valid only when you deploy your React app. On development you can access any route by only using React Router.
CodePudding user response:
This is a well known problem when deploying a SPA to github pages. To make the client side routing work, every request must be redirected to the index.html
and this behavior is not implemented by github pages.
This is explained in the create react app. It seems that you have two solutions :
- switch from using HTML5 history API to routing with hashes
- follow this guide. You must add a custom
404.html
page to your project and add a custom script tag to yourindex.html
page. I already used this solution, it worked well for me.