Preview mode bar crashes frontend after adding new content
Context
To evaluate next-drupal, I followed the quick start instructions. This was a pretty smooth process (thanks) so I continued adding some content while running the frontend with npm run dev. Then I wondered how next-drupal handles new content while running in production, so I ran npm run preview (which is short for next build && next start, the NextJS command to create and serve a production build, so I'm not sure why it is aliased "preview").
The bug
After adding new content and refreshing the frontend, I got a black bar in the top of the page saying "This page is a preview. Click here to exit preview mode." I noticed in the Chrome inspector that each mouse hover over the "Click here" link triggered a request to http://localhost:3000/_next/data/zlALAvZdtbj2TYmsbzo1-/api/exit-preview.json, but the request failed every time. Once clicked, the whole frontend application crashed. The process running npm run preview had exited too, after outputting the following error.
Error: Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=%5Bobject%20Promise%5D for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
at O (/Users/user/Code/drupal-next/frontend/node_modules/react/cjs/react.production.min.js:17:207)
at P (/Users/user/Code/drupal-next/frontend/node_modules/react/cjs/react.production.min.js:17:355)
at toArray (/Users/user/Code/drupal-next/frontend/node_modules/react/cjs/react.production.min.js:19:177)
at a.b.render (/Users/user/Code/drupal-next/frontend/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:42:249)
at a.b.read (/Users/user/Code/drupal-next/frontend/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:83)
at Object.exports.renderToString (/Users/user/Code/drupal-next/frontend/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:52:138)
at Object.renderPage (/Users/user/Code/drupal-next/frontend/node_modules/next/dist/server/render.js:768:45)
at Object.defaultGetInitialProps (/Users/user/Code/drupal-next/frontend/node_modules/next/dist/server/render.js:375:51)
at Function.getInitialProps (/Users/user/Code/drupal-next/frontend/.next/server/pages/_document.js:536:20)
at Object.loadGetInitialProps (/Users/user/Code/drupal-next/frontend/node_modules/next/dist/shared/lib/utils.js:65:29)
/Users/user/Code/drupal-next/frontend/.next/server/pages/api/exit-preview.js:16
response.clearPreviewData();
^
TypeError: response.clearPreviewData is not a function
at exit (/Users/user/Code/drupal-next/frontend/.next/server/pages/api/exit-preview.js:16:14)
at d (/Users/user/Code/drupal-next/frontend/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:33:498)
at bb (/Users/user/Code/drupal-next/frontend/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:16)
at a.b.render (/Users/user/Code/drupal-next/frontend/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:42:43)
at a.b.read (/Users/user/Code/drupal-next/frontend/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:83)
at Object.exports.renderToString (/Users/user/Code/drupal-next/frontend/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:52:138)
at Object.renderPage (/Users/user/Code/drupal-next/frontend/node_modules/next/dist/server/render.js:768:45)
at Object.defaultGetInitialProps (/Users/user/Code/drupal-next/frontend/node_modules/next/dist/server/render.js:375:51)
at Function.getInitialProps (/Users/user/Code/drupal-next/frontend/.next/server/pages/_document.js:536:20)
at Object.loadGetInitialProps (/Users/user/Code/drupal-next/frontend/node_modules/next/dist/shared/lib/utils.js:65:29)
Is this a bug? Or am I misunderstanding what next build && next start is supposed to do in the context of a next-drupal installation?
Versions used
next-drupal 1.2.1 drupal 9.3.9 nodejs 16.13.0
Looks like a bug. I've been able to reproduce this. Looking into it. Thank you.
It looks like this is a bug as reported (and marked as bug) here: https://github.com/vercel/next.js/issues/29483
Instead of using the Link component we can use a simple a tag to clear the preview.
(However, using a instead of Link will be a Eslint warning, so we can disable it for this line for now).
See below for example:
import * as React from "react"
import { useRouter } from "next/router"
export function PreviewAlert() {
const { isPreview } = useRouter()
const [showPreviewAlert, setShowPreviewAlert] = React.useState<boolean>(false)
React.useEffect(() => {
setShowPreviewAlert(isPreview && window.top === window.self)
}, [isPreview])
if (!showPreviewAlert) {
return null
}
return (
<div className="sticky top-0 left-0 z-50 w-full px-2 py-1 text-center text-white bg-black">
<p className="mb-0">
This page is a preview.{" "}
{/* eslint-disable @next/next/no-html-link-for-pages */}
<a href="/api/exit-preview" className="text-white underline">
Click here
</a>{" "}
to exit preview mode.
</p>
</div>
)
}