Next.js - Internal Server Error for previews

Hi there,

I implemented my previews like stated here https://prismic.io/docs/reactjs/getting-started/prismic-nextjs#18_0-handling-document-previews

My api/preview.tsx looks like this:

import { useEffect } from 'react'
import qs from 'qs'
import Prismic from 'prismic-javascript'
import { linkResolver } from '@utils/helpers/link-resolver'

const apiEndpoint = 'https://<REPO_NAME>.cdn.prismic.io/api/v2'

const client = Prismic.client(apiEndpoint)

const Preview = ({ history, location }) => {
  useEffect(() => {
    const { token, documentId } = qs.parse(location.search.slice(1))

    if (!token) {
      return console.warn('No token available, check your configuration')
    }

    client
      .getPreviewResolver(token, documentId)
      .resolve(linkResolver, '/')
      .then((url) => history.push(url))
  })

  return null
}

export default Preview

My preview settings look like this:
Bildschirmfoto 2020-07-30 um 18.26.51

I am getting a 500 Internal Server Error in the XHR request. And the frontend throws the error:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.

Am I missing sth here?

Hi Andi,

I’ll be happy to check this out with you.

Can you tell us what version of Prismic-Javascript you’re using?

Hi Phil, thanks for getting back. I am using 2.2.0

upgrading it to 3.0.1 didn’t help unfortunately

Ahhhh ok, the getPreviewResolver is only available using version 3.0.1 and higher. We’ll try to make this clearer in the docs.

Ah I see, in that case we need to dig deeper.

do you have any idea?

I added the api/preview.tsx inside my pages/[lang] directory and after previewing http://localhost:3000/de/api/preview?token=<TOKEN>, I do not get the server error anymore, but history, location, token and documentId are all undefined.

is this caused by SSR?

Hey Andi!

I’m sorry that you encountered an issue with the previews.
We’re currently updating the documentation to make this clearer.

Could you try and add this other configuration to your /api/preview file?

import Prismic from 'prismic-javascript'
import { linkResolver } from "./path/to/the/link-resolver.js";

const apiEndpoint = 'https://your-repo-name.cdn.prismic.io/api/v2';
const accessToken = '';

// Client method to query from the Prismic repo
const Client = (req = null) => (
  Prismic.client(apiEndpoint, createClientOptions(req, accessToken))
)

const createClientOptions = (req = null, prismicAccessToken = null) => {
  const reqOption = req ? { req } : {}
  const accessTokenOption = prismicAccessToken ? { accessToken: prismicAccessToken } : {}
  return {
    ...reqOption,
    ...accessTokenOption,
  }
}

const Preview = async (req, res) => {
  const { token: ref, documentId } = req.query;
  const redirectUrl = await Client(req).getPreviewResolver(ref, documentId).resolve(linkResolver, '/');

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

  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()
}

export default Preview

Just change the needed values to match your configuration, in this case: The path for the Link Resolver, the apiEndpoint, and the accessToken if you have one.

Let us know if this was helpful for you.

1 Like

Hi Paulina,

I think we’re getting closer here - but now I see this error message:

Uncaught Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.
    in Preview (at _app.tsx:67)

I guess this is because the Preview component doesn’t return anything. Do you have any idea?

Are you using getInitialProps in your queries?

Could you try and change this to use getStaticProps instead?

Look at the configuration in this file taken from one of our Next examples.