Nextjs Dynamic nested paths in links - Async function in linkResolver?

Hi there!

I'm working on implementing some dynamic nested routes for a multi-language website. I managed to build the paths correctly with a content relationship field linked with my page post type

export const getStaticPaths = async () => {
  const client = createClient();

  const documents = await client.getAllByType("page", { lang: "*" });

  const paths = documents.map((document) => ({
    params: {
      ctx: document.data.category.uid
        ? [document.data.category.uid, document.uid]
        : [document.uid],
      country: getLanguage(document.lang),
    },
  }));

  return { paths, fallback: false };
};

My route file is an optional catch all route

[country]/[...ctx]

So my paths are resolved like this

/country/category/doc-uid
or
/country/doc-uid

The issue comes up when I try to replicate these routes in the link resolver, this is my linkResolver function without the new routing

export function linkResolver(doc: FilledLinkToDocumentField) {
  switch (doc.type) {
    case "homepage":
      return "/";
    case "page":
      return `/${getLanguage(doc.lang)}/${doc.uid}`;
    case "blog":
      return `/${getLanguage(doc.lang)}/${doc.type}/${doc.uid}`;
    default:
      return "/";
  }
}

The problem is that the data object is not present on the doc argument passed to the linkResolver function by the PrismicProvider component, so I cannot check the category field.

I created a function to get the taxonomy for the pages, like this:

const getPageTaxonomy = async ( lang: string, uid: string | undefined ) => {
  if (!uid) return;
  const client = createClient();
  const pageData = await client.getByUID("page", uid, { lang: lang });
  return pageData.data.category;
};

And updated my linkResolver function and Prismic Resolver like this:

async function linkResolver(doc: FilledLinkToDocumentField) {
  switch (doc.type) {
    case "homepage":
      return "/";
    case "page":
      const data = await getPageTaxonomy(doc.lang, doc.uid);
      if (data?.taxonomy?.uid) {
        return `/${getLanguage(doc.lang)}/${data?.taxonomy?.uid}/${doc.uid}`;
      }
      return `/${getLanguage(doc.lang)}/${doc.uid}`;
    case "blog":
      return `/${getLanguage(doc.lang)}/${doc.type}/${doc.uid}`;
    default:
      return "/";
  }
}
<PrismicProvider
  linkResolver={(doc) =>
    Promise.resolve(linkResolver(doc)).then((url) => url)
  }
  internalLinkComponent={InternalLink}
>
.....

But my links are resolved with [promiseObject] in the hrefs.

The only way I have managed to replicate the nested paths within the links has been using tags, but this will force me to stop using the category, or to set up both category and tags in my documents:

export function linkResolver(doc: FilledLinkToDocumentField) {
  switch (doc.type) {
    case "homepage":
      return "/";
    case "page":
      if (doc.tags.length > 0)
        return `/${getLanguage(doc.lang)}/${doc.tags[0]}/${doc.uid}`;
      return `/${getLanguage(doc.lang)}/${doc.uid}`;
    case "blog":
      return `/${getLanguage(doc.lang)}/${doc.type}/${doc.uid}`;
    default:
      return "/";
  }
}

Can anyone help me determine the best approach to reach the desired route nesting in my links?

Thank you!

what happens if you add the link resolver to the PrismicProvider without the Promise.resolve and then methods?

Have you tried using the nested setup suggested in the next doc? This page teaches you how to use the Route Resolver inserted of the Link Resolver for utilizing Content Relationship fields in routes:

Same result without the Promise,resolve. Link output is [promiseObject]

I tried to follow the nested setup in the documentation defining the route variable, but I did not get the resolver to work it was throwing an error, I will post an updated version of the code because surely I did something wrong.