I noticed Amazon S3 Redirect rule - GET data is missing but after following the accepted answer my query params still are not being preserved.
I have a site that uses React and React Router, meaning I have several URLs that load identical HTML and JS and then the JS figures out which part of the app to load based on the URL.
For example:
/foo, /bar, /baz all should load index.html, which loads bundle.js. Then bundle.js observes the URL and routes to some React component (also in bundle.js).
However no foo, bar, or baz file exists in S3, only index.html. What I want to do is when I get a 404, redirect to /#!/{URL} (eg. /foo redirects to /#!/foo). This works fine with my redirect rule (below). However, I also want to bring query params with me (eg. /foo?ping=pong redirects to /#!/foo?ping=pong) but instead /foo?ping=pong just redirects to /#!/foo.
Here are my redirect rules:
<RoutingRules>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
</Condition>
<Redirect>
<Protocol>http</Protocol>
<HostName>www.mydomain.com</HostName>
<ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
</Redirect>
</RoutingRule>
</RoutingRules>
Any ideas on some way I can achieve this? Ideally without having to go change something in S3/CloudFront every time I add a new page?
The problem was that I had the origin set up in CloudFront not to forward Query Strings so when S3 got the request it would redirect properly without the query params. You can find this setting in CloudFront > Behaviors > Forward Query Strings.