@prismicio/next
Version:
Helpers to integrate Prismic into Next.js apps
76 lines (63 loc) • 2.41 kB
text/typescript
import { redirect } from "next/navigation";
import {
cookie as prismicCookie,
type Client,
type LinkResolverFunction,
} from "@prismicio/client";
import { NextRequestLike } from "./types";
export type RedirectToPreviewURLConfig = {
/** The Prismic client configured for the preview session's repository. */
// `Pick` is used to use the smallest possible subset of
// `prismic.Client`. Doing this reduces the surface area for breaking
// type changes.
client: Pick<Client, "resolvePreviewURL">;
/**
* The `request` object from a Next.js Route Handler.
*
* @see Next.js Route Handler docs: \<https://nextjs.org/docs/app/building-your-application/routing/route-handlers\>
*/
request: NextRequestLike;
/**
* A Link Resolver used to resolve the previewed document's URL.
*
* @see To learn more about Link Resolver: {@link https://prismic.io/docs/core-concepts/link-resolver-route-resolver}
*/
linkResolver?: LinkResolverFunction;
/**
* The default redirect URL if a URL cannot be determined for the previewed
* document.
*
* **Note**: If you `next.config.js` file contains a `basePath`, the
* `defaultURL` option must _not_ include it. Instead, provide the `basePath`
* property using the `basePath` option.
*/
defaultURL?: string;
};
export async function redirectToPreviewURL(
config: RedirectToPreviewURLConfig,
): Promise<never> {
const { client, request, linkResolver, defaultURL = "/" } = config;
// Need this to avoid the following Next.js build-time error:
// You're importing a component that needs next/headers. That only works
// in a Server Component which is not supported in the pages/ directory.
const { cookies, draftMode } = await import("next/headers");
const documentID =
request.nextUrl.searchParams.get("documentId") ?? undefined;
// Set the initial preview cookie. Setting the cookie here is necessary
// to support unpublished previews. Without setting it here, the page
// will try to render without the preview cookie, leading to a
// PrismicNotFound error.
const previewToken = request.nextUrl.searchParams.get("token") ?? undefined;
if (previewToken) {
const cookieJar = await cookies();
cookieJar.set(prismicCookie.preview, previewToken);
}
const previewURL = await client.resolvePreviewURL({
documentID,
previewToken,
defaultURL,
linkResolver,
});
(await draftMode()).enable();
redirect(previewURL);
}