I have built an app that doesnt have a server. It just pulls data from a couple of endpoints.
When someone tries to access a page that isnt the root URL they receive a Page not found message.
I havent managed to find a solution to this that doesnt involve writing a server. Im really hoping that I can avoid that because the app really is too simple to need it.
When I navigate to http://url.com/nextPage it returns a Page not found, but if I navigate there from the root http://url.com/ I dont have any issues.
I have not pushed an app to production before so this was an unexpected issue, but it is also important to how the app works that users are able to access a page directly via the URL.
My App.tsx file. Both pages are just straight forward React.
import { BrowserRouter as Router, Route } from 'react-router-dom';
function App() {
return (
<Router>
<Route
path='/'
exact
component={HomePage}
/>
<Route
path='/nextPage'
component={NextPage}
/>
</Router>
)
}
Since now I know you are using Netlify as your hosting provider, there is a way to do it without having your own server. Netlify has lots of configuration, one of it being redirects.
You could try adding to your Netlify.toml the following:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
Or, you could create a _redirects file, with the following content:
/* /index.html
Take a look at this documentation: https://www.netlify.com/blog/2019/01/16/redirect-rules-for-all-how-to-configure-redirects-for-your-static-site/
Related
I'm seeing an issue on Heroku that I'm not having trouble with locally. I've seen various articles and other SO posts that address this issue, and I've got an understanding that it has something to do with properly configuring the static.json file in my app in order for heroku to properly handle front end react routing, but I'm having some real trouble resolving this.
I'm using the following buildpacks and confirmed they're installed via the Heroku Dashboard > Settings:
https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku-community/static.tgz
https://github.com/mars/create-react-app-buildpack
Using a gin-gonic server and serving up ./web to serve the frontend as specified by my .Dockerfile
I have the following static.json:
{
"root": "build/",
"routes": {
"/**": "index.html"
},
"clean_urls": false,
"https_only": true,
"headers": {
"/**": {
"Strict-Transport-Security": "max-age=31557600"
}
}
}
My project structure is as follows:
/app
- /main.go
- /server
-- /server package .go files...
- /client
-- /public
-- /src
-- /remaining react related files and assets...
I have tried having the static.json file in the app root, as well as in the client dir to no avail. Still seeing 404s if I refresh on or navigate from an external site to anything but the homepage.
So, none of the static.json solutions that I found while researching this issue seemed to work. From what I gather this appears to be a known issue with react routing and/or Heroku.
That being said, if this is helpful for anyone else that comes across this issue, this is how I addressed it:
Set up a NotFound handler on the server:
All this NotFound handler do is serve up your index.html file allowing your SPA framework to handle the routing itself (making the determination if valid or truly not found).
I achieved this in go/gin-gonic by:
e := gin.New()
// gin engine set up...
e.NoRoute(func(ctx *gin.Context){
ctx.File("./web")
})
Reason being - when you hit your app normally (via the base url) you're app will serve up index.html, and then and subsequent clicks from within the app are handled via the SPA routing. But if you navigate to any other route directly (i.e. manually going to https://<your domain>.com/foo in the address bar) You will be bypassing the SPA routing and going directly to the server. This case is also achieved by simply refreshing any page other than the homepage as well.
So by serving up the index.html when you hit a not found on the server you are re-enabling the SPA framework to work its magic and serve up that route if its valid which is what we want, but also be able to handle the 404 by...
Wiring up a NotFound component in the React App:
I achieved this in React by making a simple component and wiring up a Route to consume it by registering it to path="*" as a catch all after defining all other routes:
<Router basename="/">
<Route exact path="/foo">
<FooView />
</Route>
<Route exact path="/">
<HomeView />
</Route>
<Route path="*">
<NotFoundView />
</Route>
</Router>
I tried to deploy my react app which was created using create react app to,
1.nginx
2.github pages
In both instances, only the react app logo and the title is visible in the tab but nothing appears in the body of the page. (The page is blank even though the code is deployed)
Does anyone know why this happens?
This is caused if you have used the Browser Router in your react project.
Both GitHub Pages and nginx serve your app from a non-root folder (i.e. username.github.io/repo-name/) as opposed to from a root folder (i.e. username.github.io/). React Router does not consider your app's URL as a match for any of the routes defined in your app.
For example, if you define a route using <Route exact path="/" component={SomeComponent} />, React Router will see that / and /repo-name/ do not match exactly and will, thus, not render the component.
To overcome this error use base name prop in the BrowserRouter and name it according to the non-root folder name.
example:- if your app is served inside a folder named "folder1" in your server, do as follows.
Hope my answer helps someone struggling with the same issue.cheers! #iii #R2B
I use BrowserRouter as React Router Dom, and while I try to access a specific path say http://localhost:3000/recoverPassword, the URL can't be resolved. I can't go for HashRouter as the client is not that impressed to see the # in the URL. I came across the reason and found this is how we able to rectify it using web-pack. But I don't use web-pack in my project. So I wanted to know whether is there any alternative approach without using any module bundlers?
import { BrowserRouter as Router, Route } from "react-router-dom";
class App extends Component {
render() {
return (
<Router>
<div>
<Route exact path="/" component={SignIn} />
<Route exact path="/recoverPassword" component={RecoverPassword} />
</div>
</Router>
);
}
}
Note:
Locally it works with no additional config, but when I deploy to Amazon AWS it couldn't resolve the path.
Update #1
We can configure s3 bucket to resolve the error by pointing the error document also to index.html like this answer explains. The create-react-app hash trick shall do the remaining with BrowserRouter.
But my team had hosted the build to production in EC2, I don't have
the access to it currently, need to have a look at how the same can be
configured out there. Meantime it would be great if someone can share
any info as an answer regarding how to deal this in EC2.
Thanks.
I have a nested structure where i host the react build as follows level1/level2/level3. When i hit the static hosted build using serve with localhost:3000/level1/level2/level3 it redirects correctly to localhost:3000/level1/level2/level3/title/cat/id. But when i try to hit
localhost:3000/level1/level2/level3/title1/cat1/id1 directly it just returns Not found.
I have the browser router code as follows
<BrowserRouter>
<Switch>
<Route path="/level1/level2/level3/:pageTitle/:category/:id" render={AppBody}/>
<Redirect from="/level1/level2/level3/" to="/level1/level2/level3/title/cat/id"/>
</Switch>
</BrowserRouter>
Why does default redirect work but not when we try to hit the url directly?What's the correct way to fix this?
This works just fine for me, so I think there is some other aspect of your code that is causing a problem.
Here's a code sandbox with a simple index.js that includes your router code:
https://codesandbox.io/s/vmyzkj1lvy
You can use this URL to see the results for the particular URL you mentioned:
https://vmyzkj1lvy.codesandbox.io/level1/level2/level3/title1/cat1/id1
The problem could not be actually the react router but instead your server. So first check that your server is actually returning a response when visiting /level1/level2/level3/title1/cat1/id1.
Your react router is actually changing the url in the browser when it hits <Redirect from="/level1/level2/level3/" to="/level1/level2/level3/title/cat/id"/> without sending a request to the server.
You can use this python gist as a server for static serving for your react app that I believe would solve your problem ;)
I have a website made with React running on Digital Ocean with pm2 and NGINX. The entry point "/" loads just fine but when I try to go to the "/:username" route I just get 404 Not Found. My routes are defined in App.jsx as follows:
<Switch>
<Route
exact path='/'
render={
routeProps => <Front {...routeProps} />
}
/>
<Route
path='/:username'
render={
routeProps => <Profile handleSignOut={ this.handleSignOut } {...routeProps} />
}
/>
</Switch>
index.js has the following code:
ReactDOM.render(<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
)
The routes all work as expected when running locally with npm run start.
This is a very common problem for single page apps written in different frameworks like React or Angular.
The problem, though, is irrelevant to the frameworks. It rather lies in the mechanism that is the in-browser routing. It is actually not a real routing. When you open a single page app, a simple index.html file is served, and when you navigate away inside the app, the framework takes care of rendering a new page and faking a navigation event (so that it will be recorded in the browser history and the url is changed).
But when you arrive on a subadress, like 'myapp.com/some-page', this will mke the server try and serve an actual directory called 'myapp.com/some-page', not your index.html file, which you obviously need to run the app, and, as this directory does not exist, it will throw a 404 error.
To fix this, you need to reconfigure your server, so that in case of a 404 error, instead of failing, it returns your index.html file; this way your code will be loaded and the underlying framework will handle the routing to display the correct page.
For react App hosted on app Platform on Digital Ocean.
Luckily now, you can now enable it through the UI. Please follow the steps below and it should be resolved.
Using Cloud panel UI: Log in and click on App > Settings >> click on component name > scroll down to Custom page > Edit Custom page and select Catchall > Enter index.html in the page name block > Save
Cheers,Arinze Hills
In addition to #amem nice explanation, add the following line to your web server configuration file:
For NGINX add error_page 404 /index.html;
For Apache add ErrorDocument 404 /index.html to your .htaccess