I'm working on a React app (using Create React App) with a React Router 4. Locally, everything works fine, but when I deploy it to AWS (put it in a S3 bucket and then serve it through Cloudfront), it does work, but there's an issue with the routes.
This is the problematic use case on AWS:
- instead of root
myapp
, user enters a different route, such asmyapp/login
and then attempts to navigate to the site (without being on the site at that moment) - the user gets
NoSuchKey login
error
If I try the same locally it works fine. Also, if I first go to root on AWS and then navigate to any other route, it also works fine. So the issue is just the first route which has to be root on AWS in order to load the site. I'm guessing something is wrong with my app, but I'm not sure what.
This is part of my code for routes from the render method of the top ponent that gets rendered:
return (
<Router>
<Fragment>
<Route exact path="/" ponent={Home} />
<Route path="/login" ponent={Login} />
<Route path="/forgot-password" ponent={ForgotPassword} />
<Route path="/signup" ponent={SignUp} />
<Route path="/help" ponent={Help} />
</Fragment>
</Router>
);
Any ideas?
I'm working on a React app (using Create React App) with a React Router 4. Locally, everything works fine, but when I deploy it to AWS (put it in a S3 bucket and then serve it through Cloudfront), it does work, but there's an issue with the routes.
This is the problematic use case on AWS:
- instead of root
myapp.
, user enters a different route, such asmyapp./login
and then attempts to navigate to the site (without being on the site at that moment) - the user gets
NoSuchKey login
error
If I try the same locally it works fine. Also, if I first go to root on AWS and then navigate to any other route, it also works fine. So the issue is just the first route which has to be root on AWS in order to load the site. I'm guessing something is wrong with my app, but I'm not sure what.
This is part of my code for routes from the render method of the top ponent that gets rendered:
return (
<Router>
<Fragment>
<Route exact path="/" ponent={Home} />
<Route path="/login" ponent={Login} />
<Route path="/forgot-password" ponent={ForgotPassword} />
<Route path="/signup" ponent={SignUp} />
<Route path="/help" ponent={Help} />
</Fragment>
</Router>
);
Any ideas?
Share Improve this question asked Jun 6, 2018 at 19:08 dnmhdnmh 2,1352 gold badges37 silver badges53 bronze badges1 Answer
Reset to default 10The NoSuchKey
error is actually an error from S3 - not your app itself, so what I think is happening is the user is navigating to that path and S3 is trying to find an HTML file at that path (/login
) but can't - thus the error.
The issue I believe you are running into is react router does all the route handling and routing on the client side - there isn't a physical resource on the server (or, in your case, S3) that has the actual routes.
So loading the index intially and then navigating will work because at that point, your browser has loaded the JavaScript that handles the client side routing. Navigating to a route directly (anything except the index) will cause S3 to try and find that physical file and will fail - if that makes sense.
I believe you need to change your settings in S3 to always load your index file - even if there is an error. You can do this by going to your S3 bucket's Properties, go to Static Website Hosting and make your index.html file the Index Document and the Error Document.
This way when S3 encounters the NoSuchKey
error, it will fallback to your index.html file - at which point react router will take over and figure out which route the app should be on.
Marc Garreau has a great article here on the subject which may help you out too.