'next.js export static - S3 - routing fails on page reload
I'm deploying a next.js app as a static export, to an s3 bucket configured for static website hosting.
I use next's build
and export
commands to generate the out/
directory and then copy that into my s3 bucket
The bucket then contains some files, for simplicity lets say there's just index.html
and about.html
The problem is when a user hits index.html
via www.website.com
then navigates to www.website.com/about
everything works, but reloading www.website.com/about
fails of course.
www.website.com/about.html
finds the correct asset to render the site however
Is there a way to export a static next.js app, host on s3, and have requests to /about
proxy /about.html
?
As always, thanks for looking, and thanks even more for participating.
Solution 1:[1]
The best solution I've arrived at so far, inspired by this gist: https://gist.github.com/rbalicki2/30e8ee5fb5bc2018923a06c5ea5e3ea5
Basically when deploying the build to the s3 bucket, you can simply rename the .html
files to have no .html
suffix, ex: www.bucket.com/about.html
-> www.bucket.com/about
and now both SSR & CSR routing work as expected.
The resulting files have Content-Type: text/html
despite not having the suffix, I don't know if this is problematic or not.
Solution 2:[2]
On your next.config.js
file at the root of the project.
module.exports = {
trailingSlash: true,
}
Now you can create your pages (e.g. about.jsx
) inside the pages
directory and Next will create a folder with the file name with an index.html
file inside of it when you run the export
command.
Give it a try, worked fine here.
Solution 3:[3]
RewriteRule ^([^.]+)$ $1.html [NC,L] worked fine (y)
Solution 4:[4]
Here's how Guy Hudash did it:
Assuming you already have a react.js website hosted on s3, you need to first change the S3 Routing Rules in S3 bucket -> Properties -> Static website hosting -> Redirection
rules.
The new s3 console changes the routing rules format to JSON, so you’ll need to add this (don’t forget to replace myhost.com):
[
{
"Condition": {
"HttpErrorCodeReturnedEquals": "404"
},
"Redirect": {
"HostName": "myhost.com",
"ReplaceKeyPrefixWith": "#!/"
}
},
{
"Condition": {
"HttpErrorCodeReturnedEquals": "403"
},
"Redirect": {
"HostName": "myhost.com",
"ReplaceKeyPrefixWith": "#!/"
}
}
]
These rules add #!/
as the prefix to the URL in the case of a 403
or 404
error. This solves the react-router issue and now it will load the right page.
Now we would like to remove this prefix from the url for a cleaner solution. You’ll need to edit you _app.js
and add:
import {useRouter} from 'next/router';
const MyApp = ({ Component, pageProps }) => {
const router = useRouter();
const path = (/#!(\/.*)$/.exec(router.asPath) || [])[1];
if (path) {
router.replace(path);
}
return (
<Component {...pageProps} />
);
};
export default MyApp;
You may refer to the blog-post itself... or if you are using any other routing solution than NextJS for you application, or looking for more detailed explanation then look at: Mark Biek blog
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | James |
Solution 2 | R. Karlus |
Solution 3 | letrungdo |
Solution 4 | RegarBoy |