Integrating Next.js with Prismic and Implementing Previews

Prismic is a powerful headless CMS that pairs well with Next.js, allowing developers to build fast, scalable, and SEO-friendly applications. One of Prismic's key features is its preview functionality, which enables content editors to see their unpublished changes in real-time before pushing them live.

In this guide, we’ll cover:

  1. Setting up Prismic with Next.js
  2. Fetching content from Prismic
  3. Implementing previews in Next.js
  4. Handling link resolution
  5. Using the Prismic Toolbar for a seamless editing experience

1. Setting Up Prismic with Next.js

First, if you haven’t already, create a new Next.js project and install the necessary dependencies:

npx create-next-app@latest my-prismic-app 
cd my-prismic-app
npm install @prismicio/client @prismicio/react @prismicio/helpers

Now, install the preview plugin:

npm install @prismicio/next

Then, create a Prismic configuration file (prismicio.js) to manage the Prismic API connection.

prismicio.js

import * as prismic from "@prismicio/client"; 

export const repositoryName = "your-repository-name";

export const client = prismic.createClient(repositoryName, {
accessToken: process.env.PRISMIC_ACCESS_TOKEN, // If using private API
routes: [
{ type: "homepage", path: "/" },
{ type: "post", path: "/blog/:uid" }, // Adjust based on your content types
],
});

To keep your API keys secure, store your Prismic credentials in an .env.local file:

PRISMIC_ACCESS_TOKEN=your-secret-token

2. Fetching Content from Prismic in Next.js

We can now retrieve content from Prismic using the client object. Let’s create an example page that fetches data from a homepage document.

pages/index.js

import { client } from "../prismicio"; 
import { PrismicRichText } from "@prismicio/react";

export default function Home({ homepage }) {
return (
<div>
<h1>{homepage.data.title}</h1>
<PrismicRichText field={homepage.data.content} />
</div>
);
}

export async function getStaticProps() {
const homepage = await client.getSingle("homepage");
return {
props: { homepage },
revalidate: 60, // ISR to fetch new content without rebuilding
};
}

This setup:

  • Fetches the homepage document from Prismic.
  • Uses Incremental Static Regeneration (ISR) to update content without requiring a full site rebuild.
  • Uses <PrismicRichText /> to render formatted content.

3. Implementing Previews in Next.js

Prismic allows content editors to preview unpublished changes before publishing. To enable this in Next.js, we need to configure the preview functionality.

Step 1: Configure Next.js API Route for Previews

Create an API route in pages/api/preview.js to handle preview sessions.

pages/api/preview.js

import { setPreviewData, redirectToPreviewURL } from "@prismicio/next";
import { client } from "@/prismicio";

export default async function handler(req, res) {
await setPreviewData({ req, res }); // Enables preview mode
await redirectToPreviewURL({ req, res, client }); // Redirects to the correct page
}

Step 2: Enable Preview Mode in _app.js

Update _app.js to enable Prismic previews.

pages/_app.js

import { PrismicPreview } from "@prismicio/next";
import { repositoryName } from "../prismicio";

export default function App({ Component, pageProps }) {
return (
<>
<Component {...pageProps} />
<PrismicPreview repositoryName={repositoryName} />
</>
);
}

4. Handling Link Resolution

Prismic stores links as structured content, meaning we need a link resolver to define how different document types should generate URLs.

lib/linkResolver.js

export function linkResolver(doc) {
if (doc.type === "post") {
return `/blog/${doc.uid}`;
}
if (doc.type === "homepage") {
return "/";
}
return "/";
}

Use this link resolver when fetching links in components:

Example Usage

import { PrismicPreview } from "@prismicio/next";
import { repositoryName } from "../prismicio";
import Link from "next/link";
import { PrismicLink } from "@prismicio/react";
import { linkResolver } from "../lib/linkResolver";

export default function BlogPost({ post }) {
return (
<div>
<h2>{post.data.title}</h2>
<PrismicLink document={post} linkResolver={linkResolver}>
Read More
</PrismicLink>
</div>
);
}

5. Using the Prismic Toolbar for Previews

To make the previewing experience smoother, Prismic’s Toolbar allows editors to navigate unpublished content.

Add the following to _app.js if not already included:

import { PrismicToolbar } from "@prismicio/react"; 

export default function App({ Component, pageProps }) {
return (
<>
<Component {...pageProps} />
<PrismicToolbar />
</>
);
}

This ensures that:

  • Editors see a "Preview" toolbar inside Prismic.
  • They can navigate between unpublished content directly in the preview mode.

Testing Previews

  • Enable Previews in Prismic

    - In Prismic, go to Settings → Previews.
    - Add a new preview:
    - Domain: http://localhost:3000 (or your production URL)
    - Preview Route: /api/preview
  • Start the Next.js server
npm run dev
  • Edit content in Prismic (but don't publish it)
  • Click "Preview" in Prismic
  • You’ll be redirected to the Next.js site in preview mode

Conclusion

By integrating Next.js with Prismic, we get a blazing-fast, API-driven architecture that supports previews, dynamic content, and seamless content management.

Key Takeaways

Next.js with Prismic provides high performance and flexibility
Previews allow editors to see unpublished changes in real-time
Using @prismicio/next and @prismicio/react simplifies integration
With ISR, you get dynamic content updates without full site rebuilds
Cloudflare or Vercel enhances performance & caching

This setup ensures that content editors and developers work efficiently, making Prismic + Next.js a powerful combination for modern web applications.

Tell us about your project

Contact us

Phone
01872 306121
  • Truro
    The Barn Cottage Studio
    Perranwell Station
    Truro
    Cornwall
    TR3 7NB