Dynamic routing with next export mode

Viewed 1906

We're using Next.Js in next export mode (static HTML export), and we need advanced dynamic routing.

Our routes will look like /[config1]/[config2]/[optionalConfig?]/page, where one segment is optional and the page names are fixed. For example a/b/c/page1 or a1/b1/page2. The pages need the configuration segment data to render.

I haven't found any way to do this with the built-in routing. I can do /pages/[config1]/[config2]/page1.tsx, but that optional segment seems to be an issue. Note that a custom server does not appear to be an option, as we have to use next export mode due to other constraints.

NOTE: We don't know the paths at build time; they represent part of our runtime configuration. This has to use client-side routing. (We do know the finite set of pages - say page1 ... page10 - but the routes to those pages will vary.)

I've tried switching to React Router, setting useFileSystemPublicRoutes: false and adding routes to pages/_app.tsx (Custom App). That almost works, but I see many 404s for on-demand-entries-utils.js in the console as well as some "Possible EventEmitter memory leak detected" warnings (in development mode).

Valid solutions (must work 100% client-side):

  • Way to do this with built-in routing
  • Example of integrating React Router with Next.Js
  • Alternative library (I've looked at next-routes but that hasn't been updated in 3 years)

UPDATE

We may be able to eliminate the requirement of an optional segment. However, it appears that we have to implement getStaticPaths and specify all of the routes. For example:

pages/[config]/foo.tsx

export async function getStaticPaths() {
  // Runs at build time
  return {
    paths: [{ params: { config: 'xyz' } }],
    fallback: false,
  };
}

export async function getStaticProps(context) {
  return {
    props: {},
  };
}

export default function FooPage(): JSX.Element {
  return <div>FOO</div>;
}

This will generate

┌ ○ /
├   /_app
├ ● /[config]/foo
├   └ /xyz/foo

The issue is that we do not know the config at build time.

We need dynamic client-side routing. We'd like to stay with Next.js, as eventually we may be able to use SSR, but that's not an option at the moment.

1 Answers

You can create a catch-all route to grab the parameters, including the optional one, and then you'll need to render the right component based on that. So if you created:

pages/[...config].tsx

This is the same as:

pages/[...config]/index.tsx

Then in index.tsx, you can get the config as an array of strings in getStaticProps based on the url. So /config1/config2/optional is [config1, config2, optional] and /config1/config2 is [config1, config2].

So you can use this as a directory path of sorts if you need to add additional subpages under the known and optional paths.

Related