Next.js Preview Not Hitting Link Resolver on First Load

Hi there, we've been troubleshooting an issue on our site where the preview technically works, but on the first try it simply loads to the default URL and not to the correct URL.

Based on some debugging we've been doing, it seems like our link resolver function doesn't actually get called on the initial load. Would there be a reason this is happening, why would the resolve function not hit the link resolver and just respond with the default?

Here is the code we're using which we've pulled directly from the Prismic/Nextjs example

import Prismic from "prismic-javascript";

export default async ( req: NextApiRequest, res: NextApiResponse ) => {
  const { token: ref, documentId } = req.query;

  console.log( 'PREVIEW:::', req.query )

  const redirectUrl = await Prismic.client( apiEndpoint, { req } )
    .getPreviewResolver( ref as string, documentId as string )
    .resolve( linkResolver, '/' );

  if (!redirectUrl) {
    return res.status(401).json({ message: 'Invalid token' });
  }

  console.log( "PREVIEW:", redirectUrl, ref, documentId );

  res.setPreviewData({ ref });

  res.write(
    `<!DOCTYPE html><html><head><meta http-equiv="Refresh" content="0; url=${redirectUrl}" />
    <script>window.location.href = '${redirectUrl}'</script>
    </head>`
  );
  res.end();
};

Hi there,

Thanks for reaching out.

I had a quick look at your code, and it seems ok, but I can find where you import the linkResolver, such as

import {linkResolver } from "../../prismic-configuration"

Also, can you please share the link resolver file to investigate?

For more information, you check this article. and this article for linkResolver

Best,
Fares

Thanks for responding, link resolver is imported like so:

import { linkResolver } from "@utils";

and the code for the link resolver is this:

export const linkResolver = (doc: any) => {
  const type = doc.type || doc?._meta?.type;
  const uid = doc.uid || doc?._meta?.uid;

  if (!type) return "/";

  switch (type) {
    case "project":
      return uid ? `/work/${uid}` : "/";
    case "archive_page":
      return "/archive";
    case "contact_page":
      return "/contact";
    case "culture_page":
      return "/culture";
    case "work_page":
      return "/work";
    case "careers_page":
      return "/careers";
    default:
      return "/";
  }
};

And just in case I wasn't clear in my first response, our link resolver does in fact work, but it never gets the chance to work on the first page load of a preview. It only ever gets called on the second attempt at previewing. It seems like the resolve function doesn't actually run the link resolver and instead just returns the default parameter that gets passed in.

Well, still, I need more info; when you log this "redirectUrl," what do you get, and have you add a logger in the first line of the linkResolver? are you sure it doesn't enter in the function?

Also can you remove the { req } from const redirectUrl = await Prismic.client( apiEndpoint, { req } ) and try again.

If that doesn't help, then I would need access to your project and your repository name to debug this

Yes I did have a logger before the if statement in the linkResolver that would never get hit on the first load and my log with the redirectUrl would print out '/'

I did try removing the { req } and that actually seemed to make things worse. It wouldn't route to the right page at all, even on subsequent loads.

For what it's worth we've managed to get it working a different way but it's strange that the method above doesn't work as that's what's outlined in the documentation. Here's the code that is working for us:

export default async ( req: NextApiRequest, res: NextApiResponse ) => {
  const { token: ref, documentId } = req.query;

  const previewClient = (req: NextApiRequest) =>
    Prismic.client(apiEndpoint, { ...req, accessToken: process.env.PRISMIC_ACCESS_TOKEN });

  const doc = await previewClient(req).getByID(documentId as string, { ref });
  const url = linkResolver(doc);

  if (!url) {
    return res.status(401).json({ message: 'Invalid token' });
  }

  res.setPreviewData({ ref });

  res.write(
    `<!DOCTYPE html><html><head><meta http-equiv="Refresh" content="0; url=${url}" />
    <script>window.location.href = '${url}'</script>
    </head>`
  );
  res.end();
};

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

I've debugged this again and I'm not sure of the reason why this is not working for, one last check maybe to check if you are using @prismicio/client kit V4.0.0 and above

In fact, the first way you have implemented this looks very similar to what mentioned in the documentation

For that, I will create an issue in our issue tracker to have somebody from the dev team check this, and also it would useful if you can share with us your project source code (in a private message) in order to debug the problem.

This thread is being monitored as an open ticket in the issue tracker. We will update this post as we get more information. If you have a similar use-case, you can ‘Flag’ this topic to reopen.