Nextjs Previews

Good afternoon. I'm unable to get the Preview function to work with NextJs. I've created a basic app via npx create-next-app@latest I then ran the npx @slicemachine/init@latest. I followed all instructions as per this url -> Install Prismic with Next.js - Documentation - Prismic. However when attempting to preview a draft document, I can see that /api/preview is triggered, and then it redirects to the correct route, I can see the toolbar installed. However the draft content is not displaying. I'm getting either the previous published version or document not found in the case of a unpublished draft document.

slicemachine.config.json looks as follows;

{
  "repositoryName": "myrise",
  "adapter": "@slicemachine/adapter-next",
  "libraries": ["./src/slices"],
  "localSliceSimulatorURL": "http://localhost:3000/slice-simulator"
}

prismicio.ts as follows

import * as prismic from "@prismicio/client";
import * as prismicNext from "@prismicio/next";
import config from "../slicemachine.config.json";

/**
 * The project's Prismic repository name.
 */
export const repositoryName = config.repositoryName;

/**
 * A list of Route Resolver objects that define how a document's `url` field is resolved.
 *
 * {@link https://prismic.io/docs/route-resolver#route-resolver}
 */
// TODO: Update the routes array to match your project's route structure.
const routes: prismic.ClientConfig["routes"] = [
  {
    type: "blog-posts",
    path: "/stories/:uid"
  }
];

/**
 * Creates a Prismic client for the project's repository. The client is used to
 * query content from the Prismic API.
 *
 * @param config - Configuration for the Prismic client.
 */
export const createClient = (config: prismicNext.CreateClientConfig = {}) => {
  const client = prismic.createClient(repositoryName, {
    routes,
    accessToken: "....", removed for security but the correct token is present.
    fetchOptions:
      process.env.NODE_ENV === "production"
        ? { next: { tags: ["prismic"] }, cache: "force-cache" }
        : { next: { revalidate: 5 } },
    ...config,
  });

  prismicNext.enableAutoPreviews({
    client,
    previewData: config.previewData,
    req: config.req,
  });

  return client;
};

layout.tsx as follows

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
      {children}
      <PrismicPreview repositoryName={repositoryName} />
      </body>
    </html>
  )
}

api/preview/route.ts as follows

import { NextRequest } from "next/server";
import { redirectToPreviewURL } from "@prismicio/next";

import { createClient } from "@/prismicio";
import {draftMode} from "next/headers";

export async function GET(request: NextRequest) {
  const client = createClient();

  await redirectToPreviewURL({ client, request });
}

/stories/[uid]/page.tsx as follows;

import { createClient } from "@/prismicio";

export default async function Page({ params }: { params: { uid: string }}) {
    const client = createClient();

    const page = await client.getByUID("blog-posts", params.uid);

    return <div>{JSON.stringify(page)}</div>;
}

I can confirm that a cookie is being set io.prismic.preview with a ref that I can use via a graphql query to verify the document.

package.json as follows;

{
  "name": "app-test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "slicemachine": "start-slicemachine"
  },
  "dependencies": {
    "@prismicio/client": "^7.2.0",
    "@prismicio/next": "^1.3.4",
    "@prismicio/react": "^2.7.2",
    "@types/node": "20.6.0",
    "@types/react": "18.2.21",
    "@types/react-dom": "18.2.7",
    "autoprefixer": "10.4.15",
    "eslint": "8.49.0",
    "eslint-config-next": "13.4.19",
    "next": "13.4.19",
    "postcss": "8.4.29",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tailwindcss": "3.3.3",
    "typescript": "5.2.2"
  },
  "devDependencies": {
    "@slicemachine/adapter-next": "^0.3.14",
    "slice-machine-ui": "^1.12.0"
  }
}

Any assistance would be appreciated, however this is the most basic of setup and it does not appear to be working.

Hi, @dev40. I'm sorry that you're having trouble with previews on your project. This is quite strange. Not only does it appear that you've set everything up correctly, but I created a brand new project and set it all up exactly as you show above, and everything is working properly for me.

I'm not sure how to advise you on this as a result. I guess the next thing to try would be running a preview directly from your repository. If you give me your permission to view your repository, then you can DM a link to a document in Prismic, describe the changes I should look for in the preview, and I can run a preview of your repo to see if it works or not for me.

Thanks Levi for taking a look at this. I'm completely puzzled as well. I figured maybe something in my main project might have been causing issues hence why I set up a basic project as explained above. You can most certainly take a look a doing a preview directory from our repo. Let me know if you need any extra information.

To add some more information, we have an old version of our application which is just JS and React, and the previews work fine for our repo for that application.

UPDATE: I started looking at some of the example repo's that I saw with Prismic and NextJS and noticed that they used an older version of NextJS. I rolled back the NextJS version from 13.4.19 to 13.4.12 and presto previews started working. Some more info, I tried 13.4.13 -> 13.4.19 all didn't work. The latest canary version 13.4.20-canary.26 is working.

Thanks again.

@dev40 You're welcome and I'm mostly happy that you were able to get things working. And thanks so much for the detailed analysis. That will be helpful if we have anyone else reporting issues with this.

But it's still strange to me because everything was working perfectly for me with version 13.4.19.

In any case, take care and thanks again for the info on how you got it working again :slight_smile:

1 Like

Hi

I'm revisiting Prismic as a potential CMS and have been very impressed with the Slice Machine, however I am having an issues with previews which if not fixed will stop me adopting Prismic.

My issue is very similar to this thread, hence why I posted here. I am using the latest version of Next and Slice Machine and have tried in my normal project and a new minimal project but both have the same result.

When trying to view a preview the following returns an empty array:

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

	const pages = await client.getAllByType('page');

	return pages.map((page) => {
		return {
			uid: page.uid,
		};
	});
};
```
And then the following returns an error:

```
const Page = async ({ params }: IPageProps) => {
	const client = createClient();

	const page = await client.getByUID('page', params.uid).catch((err) => {
		// console.log('app/[uid]/page > Page():', err);

		notFound();
	});

	return <SliceZone slices={page?.data.slices} components={components} />;
};
```
```
[next]   response: {
[next]     type: 'api_parsing_error',
[next]     message: `[function at(..)] unexpected field 'my.page.uid' on line:1 col:6 in query '[[at(my.page.uid, "renderer.js.map")]]'\n` +
[next]       '[[at(my.page.uid, "renderer.js.map")]]\n' +
[next]       '     ^\n',
[next]     pos: { line: 1, column: 6, id: 1, location: 'query' }
[next]   }
``````
When I publish a document, I can view it.

I have looked at a number of topics regarding previews not working and haven't been able to find a solution so am hoping you can help me here.

I can now confirm that previews seem to be working on a deployed environment but I still can't them working locally. Also, is it possible to view previews using the API in a tool like Insomnia?

We don't currently have any guides to installing Prismic with Insomnia. I'd recommend using Prismic previews alone but I'm not entirely sure how Insomnia works. I'd be curious to hear about your solution if you create this integration.