arnaudambro
arnaudambro

Reputation: 2653

Next.js static export, routes, dynamic routes and .htaccess

TDLR;

Any idea what would be the best way to achieve successful reload of dynamic routing in a static export of a next.js app (next build && next export) without getStaticPaths ?

When I was working with create-react-app and react-router, I had to add the following .htaccess file in the /public folder which would be copied/pasted int he output /build folder

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]
</IfModule>

It allows for any page reload from any route to be redirected to the correct route within the app, instead of having a 404.

With Next.js, as a static site connected to an external api, it seems a bit more complicated to have that kind of behaviour with dynamic routes. It's not dynamic routes that I can generate with getStaticPaths because I can't anticipate those paths.

My page is a quizz where you can see your results and share them if you wish. So that I have

It's been very hard to make the page reload working properly, without a 403 or 404. I've tried a lot of stuff, like

const moduleExports = {
  reactStrictMode: true,
  exportPathMap: () => ({
    "/": { page: "/" },
    "/result/arnaud": { page: "/result" },
  }),
  images: {
    loader: "imgix",
    path: "",
  },
  trailingSlash: true,
};

What I ended up doing is a trick : in the index.js at the root of my pages, the one showing for the path /:

const router = useRouter();

  useEffect(() => {
    if (router.asPath?.includes("result") && router.asPath?.split("/").length > 1) {
      router.push(router.asPath);
    }
  }, [router.asPath]);

It's actually doing the trick, but I don't like that so much. It was much easier with a reliable .htaccess that I could blindly copy paste from projects to projects.

Anything better ?

Upvotes: 4

Views: 2866

Answers (1)

Mohammad Mahdi Kabir
Mohammad Mahdi Kabir

Reputation: 790

I think best way for normal routes is:

Open next.config.js and add the trailingSlash config:

module.exports = {
  trailingSlash: true,
}

More info: https://nextjs.org/docs/app/api-reference/next-config-js/trailingSlash

For dynamic routes should to add a .htaccess file for every dynamic routes. for example:

Suppose this is the structure of a dynamic route after build:

product/[pid]/index.html

Add a .htaccess file in product folder like this:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^(.*) /product/[pid]/index.html [NC,L]

Upvotes: 0

Related Questions