# Next.js with previews and Draft Mode

**URL:** <https://community.prismic.io/t/next-js-with-previews-and-draft-mode/13234>\
**Category:** Developing with Prismic\
**Created:** [May 31, 2023, 12:31am UTC](https://community.prismic.io/t/next-js-with-previews-and-draft-mode/13234 "2023-05-31T00:31:35Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![angeloashmore](https://dub1.discourse-cdn.com/flex013/user_avatar/community.prismic.io/angeloashmore/32/2685_2.png) [@angeloashmore](https://community.prismic.io/u/angeloashmore)\
**Post date:** [May 31, 2023, 12:31am UTC](https://community.prismic.io/t/next-js-with-previews-and-draft-mode/13234/1 "2023-05-31T00:31:36Z")

</div>

Hey everyone,

I'm Angelo, one of Prismic's engineers working on our Next.js integration.

We are working toward full support for Prismic projects built using [the new App Router](https://nextjs.org/docs/app). Preview support is the last major piece we are working on before we can fully recommend the App Router.

We are close to a solution you can use today, but it has some caveats, such as only working with dynamic rendering, where we would normally recommend using static rendering. You can [learn the differences between dynamic and static rendering in the Next.js docs](https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic-rendering). We will be publishing documentation on setting up an experimental version of preview support soon.

We opened a feature request for Next.js that would allow us to implement Prismic previews using static rendering, which would allow for better performance over the experimental preview support. You can see the request here:

> **[Support dynamic functions in Draft Mode in otherwise statically rendered pages...](https://github.com/vercel/next.js/discussions/50399)**
>
> Goals Enhance Draft Mode by supporting cookies() or adding the ability to set and read serializable data while Draft Mode is enabled in normally statically rendered pages. Retain the performance of...

You can share your support for the feature request by giving it an upvote and 👍.

If you have any questions about the status of Next.js and Prismic previews in the App Router, please leave them here. Thank you for your support!

---

<div class="post-metadata">

**Author:** ![gabriel](https://avatars.discourse-cdn.com/v4/letter/g/9de0a6/32.png) [@gabriel](https://community.prismic.io/u/gabriel)\
**Post date:** [June 6, 2023, 3:41pm UTC](https://community.prismic.io/t/next-js-with-previews-and-draft-mode/13234/2 "2023-06-06T15:41:28Z")

</div>

Hey @angeloashmore, this is the last piece missing for my team to adopt the new App router. We currently have a PR on hold due to the missing preview feature. Could you provide a bit more guidance on how to use the preview forcing the dynamic mode? I'd tried to add it to the root layout but it isn't working, even for localhost previews.

```auto
/app/layout.tsx

export const dynamic = 'force-dynamic'

...

```

---

<div class="post-metadata">

**Author:** ![angeloashmore](https://dub1.discourse-cdn.com/flex013/user_avatar/community.prismic.io/angeloashmore/32/2685_2.png) [@angeloashmore](https://community.prismic.io/u/angeloashmore)\
**Post date:** [June 6, 2023, 6:59pm UTC](https://community.prismic.io/t/next-js-with-previews-and-draft-mode/13234/3 "2023-06-06T18:59:39Z")

</div>

Hey @gabriel,

I'm glad to hear you have everything else working in the App Router! 🙂

We don't have the updated Preview + App Router docs published yet, but I can share fragments of it here.

The Next.js team is working on [the proposal described in the discussion above](https://github.com/vercel/next.js/discussions/50399) which will ultimately replace the strategy explained below. However, much of the implementation will use the same APIs (`<PrismicPreview>`, `enableAutoPreviews()`, etc.).

When an updated version of Next.js is released with Draft Mode + `cookies()` support, we will post an updated guide with the correct usage.

Until then, here's how you can use previews today with the App Router and dynamic rendering (content taken from an draft version of an upcoming tutorial).

If you have any questions, please leave them here. Thanks! 😄

  

* * *
  

# Set up `createClient()`

Ensure your `createClient()` function uses the following `fetchOptions` and calls `enableAutoPreviews()`.

```diff
// src/prismicio.js

  import * as prismic from '@prismicio/client'
  import * as prismicNext from '@prismicio/next'

  export const createClient = (config = {}) => {
    const client = prismic.createClient(repositoryName, {
+ fetchOptions: {
+ cache: process.env.NODE_ENV === "production" ? "force-cache" : "no-store",
+ next: { tags: ['prismic'] },
+ },
      ...config,
    })

+ prismicNext.enableAutoPreviews({ client })

    return client
  }

```

# Set up previews

> Prismic Previews in the App Router are currently experimental and only supported using [dynamic rendering](https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-rendering). All Prismic API requests are cached at request time, resulting in performance similar to [static rendering](https://nextjs.org/docs/app/building-your-application/rendering#static-rendering).
> 
> If you prefer static rendering, remove Prismic Preview support or use the Pages Router.

### Add `<PrismicPreview>` to your layout

Prismic Previews require the Prismic Toolbar and a framework integration to work. `@prismicio/next` provides all the code you need in a simple `<PrismicPreview>` component.

Add the component to your global layout in `src/app/layout.tsx`.

```diff
// src/app/layout.tsx

+ import { PrismicPreview } from "@prismicio/next";

+ import { repositoryName } from "@/prismicio";

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

```

### Create a `/preview` Route Handler

A small bridge is needed between Prismic and your Next.js website to support previews. You can connect the two by creating a Route Handler, which will redirect content writers from Prismic to their previewed document’s webpage.

1. Create a directory named `preview` within the `src/app` directory.
2. Within the `src/app/preview` directory, create a file named `route.ts` and paste in the code below.

```tsx
// src/app/preview/route.ts

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

import { createClient } from "@/prismicio";

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

  await redirectToPreviewURL({ client, request });
}

```

### Set up previews in Prismic

You’ll need to tell Prismic your app’s URL in order to preview content.

1. Go to your Prismic repository.
2. Open the settings page using the gear icon in the bottom left corner.
3. Select Previews in the sidebar.
4. Fill out the fields with these values:  
**Site Name** : Development  
**Domain** : `http://localhost:3000`  
**Preview Route** : `/preview`
5. Click “Create my Preview”

Add other preview endpoints as needed, such as your production URL.

# Set up On-demand Revalidation

Your app is configured to cache all Prismic queries indefinitely for the best performance. However, you’ll want to fetch new content after you publish documents in Prismic.

In this last step of this tutorial, you’ll set up [On-demand Revalidation](https://nextjs.org/docs/app/building-your-application/data-fetching/revalidating#on-demand-revalidation) to do exactly that: Prismic will be configured to call one of your app’s endpoints to clear Next.js’ network cache upon content changes.

On-demand Revalidation won’t have an effect until you deploy your app. If you don’t plan to deploy your app, you can skip this section.

1. Create a directory named `revalidate` within the `src/app` directory.
2. Within the `src/app/revalidate` directory, create a file named `route.ts` and paste in the code below.

```tsx
// src/app/revalidate/route.ts

import { revalidateTag } from 'next/cache'
import { NextResponse } from 'next/server'

export async function POST() {
  revalidateTag('prismic')

  return NextResponse.json({ revalidated: true, now: Date.now() })
}

```

### Set up On-demand Revalidation in Prismic

Once your app is deployed and has a public URL, you’ll need to create a Prismic webhook pointed to the `/revalidate` endpoint.

1. Go to your Prismic repository.
2. Open the settings page using the gear icon in the bottom left corner.
3. Select Webhooks in the sidebar.
4. Fill out the fields with these values:  
**Name of the Webhook** : Next.js On-Demand Revalidation  
**URL** : Your app’s deployed URL + `/revalidate` (example: `https://example.com/revalidate`)  
**Triggers** : Only check “A document is published” and “A document is unpublished”
5. Click “Add this webhook”.

You can test everything is working by publishing an edit to a document and viewing its page on your deployed website. You should see your changes reflected practically immediately after publishing.

---

<div class="post-metadata">

**Author:** ![gabriel](https://avatars.discourse-cdn.com/v4/letter/g/9de0a6/32.png) [@gabriel](https://community.prismic.io/u/gabriel)\
**Post date:** [June 7, 2023, 7:28pm UTC](https://community.prismic.io/t/next-js-with-previews-and-draft-mode/13234/4 "2023-06-07T19:28:20Z")

</div>

Oh great! That will be super helpful!

Is there a way we can use the preview mode and on-demand revalidation at the same time with both /pages and /app directories?

Is the on-demand revalidation step mandatory for the preview work? currently, a few platforms such as Netlify don't support that feature yet
