Nested Dynamic Routes with Nextjs and Prismic

"@prismicio/client": "^7.21.0",
"next": "^16.0.7",

I want the URL structure:
/resources/:resource_type/:uid

My routes look like:
const routes: Route = [
{ type: "page", uid: "home", path: "/" },
{ type: "page", path: "/:uid" },
{ type: "resource_type", path: "/resources/:resource_type" },
{
type: "resource",
resolvers: { resource_type: "resource_type" },
path: "/resources/:resource_type/:uid"
}
];

My folder structure looks like:
—page.tsx
—[uid]
——page.tsx
—resources
——[resource_type]
————page.tsx
————[uid]
——————page.tsx

//resources/[resource_type]/page.tsx

import { createClient } from "@/prismicio";

type Params = { resource_type: string };

export default async function ResourceTypePage({
params
}: {
params: Promise;
}) {
const { resource_type } = await params;
const client = createClient();
const doc = await client.getByUID("resource_type", resource_type);

return <>{doc.data.title}</>;

}

//resources/[resource_type]/[uid]/page.tsx

import { createClient } from "@/prismicio";

type Params = { uid: string };

export default async function ResourcePage({
params
}: {
params: Promise;
}) {
const { uid } = await params;
const client = createClient();
const doc = await client.getByUID("resource", uid);

return <>{doc.data.title}</>;

}

Accessing:
localhost:3000/resources/talks
localhost:3000/resources/talks/talk-one

gives the error:

[Link resolver error] The following resolvers are missing for page type resource_type:

  • resource
    [Link resolver error] The following resolvers are missing for page type resource:

  • resource
    src/app/resources/[resource_type]/page.tsx (12:14) @ ResourceTypePage

    10 | const { resource_type } = await params;
    11 | const client = createClient();

12 | const doc = await client.getByUID("resource_type", resource_type);
| ^
13 |
14 | return <>{doc.data.title}</>;
15 | }

Page type: Resource
has content relationship field linking it to
Page type: Resource Type

How do I fix it?!

Hey @ed11,

That error is coming from Prismic’s Route Resolver, not Next.js.

In routes, any path segment that isn’t one of the built-ins (:uid, :lang, :type, :id) must be backed by a resolver (a content relationship field on that document).
So this route is the culprit:

{ type: "resource_type", path: "/resources/:resource_type" }

For documents of type resource_type, :resource_type is not a built-in param, and you didn’t provide a resolver for it — so Prismic complains (and it cascades when resolving resource docs too).

Fix

Use :uid for the resource_type route:

import type { Route } from "@prismicio/client";

export const routes: Route[] = [
  { type: "page", uid: "home", path: "/" },
  { type: "page", path: "/:uid" },

  // resource_type UID lives here
  { type: "resource_type", path: "/resources/:uid" },

  // resource has a content relationship field that points to resource_type
  {
    type: "resource",
    resolvers: { resource_type: "resource_type" }, // MUST match the field API ID on `resource`
    path: "/resources/:resource_type/:uid",
  },
];

This will generate:

  • resource_type doc (uid = talks) → /resources/talks
  • resource doc (uid = talk-one, resource_type relationship uid = talks) → /resources/talks/talk-one

Also worthh checking:

Make sure the key in resolvers matches the API ID of the content relationship field on resource.

If the field API ID in Prismic is actually resourceType or type or category etc, then this must match exactly:

resolvers: { category: "resource_type" }
path: "/resources/:category/:uid"

If it doesn’t match, Prismic will keep saying resolvers are missing.

Additionally, your Next.js pages typing (not the main issue, but should be fixed):

In Next App Router, params is not a Promise:

export default async function ResourceTypePage({ params }: { params: { resource_type: string } }) {
  const client = createClient();
  const doc = await client.getByUID("resource_type", params.resource_type);
  return <>{doc.data.title}</>;
}
export default async function ResourcePage({ params }: { params: { uid: string } }) {
  const client = createClient();
  const doc = await client.getByUID("resource", params.uid);
  return <>{doc.data.title}</>;
}