Handling Props Type Error with Auth0's Next.js Library

I’m using the Auth0 library for Next.js and encountering a type error with a Page component that requires authentication.

In the following Page component, I want to accept a URL query string like ?foo=something. I would like to explicitly represent this in the Props Interface:

import { withPageAuthRequired } from "@auth0/nextjs-auth0";

interface Props {
  searchParams: {
    foo: string;
  };
}

export default withPageAuthRequired(
  async function Page(props: Props) {
    return <div>{props.searchParams.foo}</div>;
  },
  { returnTo: "/" },
);

However, when using withPageAuthRequired , I get a type error because the type differs from AppRouterPageRouteOpts:

TS2345: Argument of type (props: Props) => Promise<Element> is not assignable to parameter of type AppRouterPageRout

AppRouterPageRouteOpts is defined as follows. If I don’t explicitly define the Props Interface, there is no type error, but the specification of the Page component becomes unclear, and I would like to represent it explicitly:

export type AppRouterPageRouteOpts = {
  params?: Record<string, string | string[]>;
  searchParams?: { [key: string]: string | string[] | undefined };
};

Is there a good way to handle this?

1 Like

Did you figure this out? I also have this problem.

I’m having the same issue, and the cause is that AppRouterPageRouteOpts expects params and searchParams to be optional values, so they must be typed as such in the page props.

I don’t know if there are chances of Next.js generating pages without providing values for this props. For params I think it makes no sense that is is optional: the page will only be targeted by the router if someone requests it with a dynamic parameter, so I cannot imagine a situation where it is undefined.

For searchParams it could make sense, as someone could write the URL deleting the query parameters and the page would nonetheless be targeted by the router. However, in these situations Next.js provides an empty object for searchParams, not undefined.

Therefore, I think AppRouterPageRouteOpts is wrongly typed.

One solution is to make params and searchParams optional in our pages, but I don’t see the reason for that and it leads to unnecessary null checks before using those parameters.

As this is only an Auth0 requirement, I prefer to leave the page untouched and use a type assertion (as AppRouterPageRoute) when using withPageAuthRequired:

export default withPageAuthRequired(
  async function Page(props: Props) {
    return <div>{props.searchParams.foo}</div>;
  } as AppRouterPageRoute,
  { returnTo: "/" },
);
1 Like

Agree with everything here. This is one of the most confounding type issues I’ve dealt with in a while. Thanks for the solution.