@prismicio/next 1.7.0 → 2.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/dist/PrismicNextImage.d.ts +7 -8
- package/dist/PrismicNextImage.js +8 -8
- package/dist/PrismicNextImage.js.map +1 -1
- package/dist/PrismicNextLink.d.ts +99 -100
- package/dist/PrismicNextLink.js +3 -5
- package/dist/PrismicNextLink.js.map +1 -1
- package/dist/PrismicPreview.d.ts +5 -13
- package/dist/PrismicPreview.js +6 -9
- package/dist/PrismicPreview.js.map +1 -1
- package/dist/PrismicPreviewClient.d.ts +5 -3
- package/dist/PrismicPreviewClient.js +58 -69
- package/dist/PrismicPreviewClient.js.map +1 -1
- package/dist/createLocaleRedirect.d.ts +8 -15
- package/dist/createLocaleRedirect.js +4 -28
- package/dist/createLocaleRedirect.js.map +1 -1
- package/dist/enableAutoPreviews.d.ts +7 -31
- package/dist/enableAutoPreviews.js +24 -35
- package/dist/enableAutoPreviews.js.map +1 -1
- package/dist/exitPreview.d.ts +5 -47
- package/dist/exitPreview.js +8 -15
- package/dist/exitPreview.js.map +1 -1
- package/dist/imgixLoader.js.map +1 -1
- package/dist/index.d.ts +15 -18
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/devMsg.d.ts +1 -1
- package/dist/lib/devMsg.js.map +1 -1
- package/dist/package.json.js +1 -1
- package/dist/pages/PrismicPreview.d.ts +31 -0
- package/dist/pages/PrismicPreview.js +64 -0
- package/dist/pages/PrismicPreview.js.map +1 -0
- package/dist/pages/enableAutoPreviews.d.ts +31 -0
- package/dist/pages/enableAutoPreviews.js +19 -0
- package/dist/pages/enableAutoPreviews.js.map +1 -0
- package/dist/pages/exitPreview.d.ts +33 -0
- package/dist/pages/exitPreview.js +10 -0
- package/dist/pages/exitPreview.js.map +1 -0
- package/dist/pages/index.d.ts +18 -0
- package/dist/pages/redirectToPreviewURL.d.ts +43 -0
- package/dist/pages/redirectToPreviewURL.js +16 -0
- package/dist/pages/redirectToPreviewURL.js.map +1 -0
- package/dist/{setPreviewData.d.ts → pages/setPreviewData.d.ts} +3 -9
- package/dist/{setPreviewData.js → pages/setPreviewData.js} +2 -2
- package/dist/pages/setPreviewData.js.map +1 -0
- package/dist/pages/types.d.ts +30 -0
- package/dist/pages.js +21 -0
- package/dist/pages.js.map +1 -0
- package/dist/redirectToPreviewURL.d.ts +11 -41
- package/dist/redirectToPreviewURL.js +16 -22
- package/dist/redirectToPreviewURL.js.map +1 -1
- package/dist/types.d.ts +2 -51
- package/package.json +61 -54
- package/src/PrismicNextImage.tsx +19 -16
- package/src/PrismicNextLink.tsx +17 -13
- package/src/PrismicPreview.tsx +18 -30
- package/src/PrismicPreviewClient.tsx +111 -138
- package/src/createLocaleRedirect.ts +14 -56
- package/src/enableAutoPreviews.ts +38 -110
- package/src/exitPreview.ts +18 -79
- package/src/index.ts +15 -26
- package/src/lib/devMsg.ts +1 -1
- package/src/pages/PrismicPreview.tsx +145 -0
- package/src/pages/enableAutoPreviews.ts +62 -0
- package/src/pages/exitPreview.ts +45 -0
- package/src/pages/index.ts +27 -0
- package/src/pages/redirectToPreviewURL.ts +77 -0
- package/src/{setPreviewData.ts → pages/setPreviewData.ts} +5 -11
- package/src/pages/types.ts +36 -0
- package/src/redirectToPreviewURL.ts +44 -95
- package/src/types.ts +2 -56
- package/dist/PrismicNextImage.cjs +0 -64
- package/dist/PrismicNextImage.cjs.map +0 -1
- package/dist/PrismicNextLink.cjs +0 -40
- package/dist/PrismicNextLink.cjs.map +0 -1
- package/dist/PrismicPreview.cjs +0 -18
- package/dist/PrismicPreview.cjs.map +0 -1
- package/dist/PrismicPreviewClient.cjs +0 -81
- package/dist/PrismicPreviewClient.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/cookie.cjs +0 -5
- package/dist/_node_modules/@prismicio/client/dist/cookie.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/cookie.js +0 -5
- package/dist/_node_modules/@prismicio/client/dist/cookie.js.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/errors/PrismicError.cjs +0 -16
- package/dist/_node_modules/@prismicio/client/dist/errors/PrismicError.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/errors/PrismicError.js +0 -16
- package/dist/_node_modules/@prismicio/client/dist/errors/PrismicError.js.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/getToolbarSrc.cjs +0 -13
- package/dist/_node_modules/@prismicio/client/dist/getToolbarSrc.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/getToolbarSrc.js +0 -13
- package/dist/_node_modules/@prismicio/client/dist/getToolbarSrc.js.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/helpers/asLink.cjs +0 -47
- package/dist/_node_modules/@prismicio/client/dist/helpers/asLink.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/helpers/asLink.js +0 -47
- package/dist/_node_modules/@prismicio/client/dist/helpers/asLink.js.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/helpers/asLinkAttrs.cjs +0 -28
- package/dist/_node_modules/@prismicio/client/dist/helpers/asLinkAttrs.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/helpers/asLinkAttrs.js +0 -28
- package/dist/_node_modules/@prismicio/client/dist/helpers/asLinkAttrs.js.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/helpers/documentToLinkField.cjs +0 -27
- package/dist/_node_modules/@prismicio/client/dist/helpers/documentToLinkField.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/helpers/documentToLinkField.js +0 -27
- package/dist/_node_modules/@prismicio/client/dist/helpers/documentToLinkField.js.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/helpers/isFilled.cjs +0 -14
- package/dist/_node_modules/@prismicio/client/dist/helpers/isFilled.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/helpers/isFilled.js +0 -14
- package/dist/_node_modules/@prismicio/client/dist/helpers/isFilled.js.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/isRepositoryName.cjs +0 -7
- package/dist/_node_modules/@prismicio/client/dist/isRepositoryName.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/isRepositoryName.js +0 -7
- package/dist/_node_modules/@prismicio/client/dist/isRepositoryName.js.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/lib/isInternalURL.cjs +0 -9
- package/dist/_node_modules/@prismicio/client/dist/lib/isInternalURL.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/lib/isInternalURL.js +0 -9
- package/dist/_node_modules/@prismicio/client/dist/lib/isInternalURL.js.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/types/value/link.cjs +0 -10
- package/dist/_node_modules/@prismicio/client/dist/types/value/link.cjs.map +0 -1
- package/dist/_node_modules/@prismicio/client/dist/types/value/link.js +0 -10
- package/dist/_node_modules/@prismicio/client/dist/types/value/link.js.map +0 -1
- package/dist/createLocaleRedirect.cjs +0 -32
- package/dist/createLocaleRedirect.cjs.map +0 -1
- package/dist/enableAutoPreviews.cjs +0 -40
- package/dist/enableAutoPreviews.cjs.map +0 -1
- package/dist/exitPreview.cjs +0 -20
- package/dist/exitPreview.cjs.map +0 -1
- package/dist/imgixLoader.cjs +0 -17
- package/dist/imgixLoader.cjs.map +0 -1
- package/dist/index.cjs +0 -21
- package/dist/index.cjs.map +0 -1
- package/dist/lib/devMsg.cjs +0 -8
- package/dist/lib/devMsg.cjs.map +0 -1
- package/dist/lib/getPreviewCookieRepositoryName.cjs +0 -7
- package/dist/lib/getPreviewCookieRepositoryName.cjs.map +0 -1
- package/dist/lib/getPreviewCookieRepositoryName.d.ts +0 -9
- package/dist/lib/getPreviewCookieRepositoryName.js +0 -7
- package/dist/lib/getPreviewCookieRepositoryName.js.map +0 -1
- package/dist/lib/getPrismicPreviewCookie.cjs +0 -21
- package/dist/lib/getPrismicPreviewCookie.cjs.map +0 -1
- package/dist/lib/getPrismicPreviewCookie.d.ts +0 -9
- package/dist/lib/getPrismicPreviewCookie.js +0 -21
- package/dist/lib/getPrismicPreviewCookie.js.map +0 -1
- package/dist/package.json.cjs +0 -5
- package/dist/package.json.cjs.map +0 -1
- package/dist/redirectToPreviewURL.cjs +0 -30
- package/dist/redirectToPreviewURL.cjs.map +0 -1
- package/dist/setPreviewData.cjs +0 -11
- package/dist/setPreviewData.cjs.map +0 -1
- package/dist/setPreviewData.js.map +0 -1
- package/src/lib/getPreviewCookieRepositoryName.ts +0 -14
- package/src/lib/getPrismicPreviewCookie.ts +0 -33
|
@@ -1,60 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { match } from "@formatjs/intl-localematcher";
|
|
3
|
-
import * as prismic from "@prismicio/client";
|
|
4
|
-
|
|
5
|
-
import { NextRequestLike } from "./types";
|
|
6
|
-
|
|
7
|
-
export type CreateLocaleRedirectConfig = {
|
|
8
|
-
request: NextRequestLike;
|
|
9
|
-
client: Pick<prismic.Client, "getRepository">;
|
|
10
|
-
localeOverrides?: Record<string, string>;
|
|
11
|
-
omitDefaultLocale?: boolean;
|
|
12
|
-
};
|
|
1
|
+
import { devMsg } from "./lib/devMsg.js";
|
|
13
2
|
|
|
14
3
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* locale.
|
|
18
|
-
*
|
|
19
|
-
* @returns A `Response` if the request should be redirected, `undefined`
|
|
20
|
-
* otherwise.
|
|
4
|
+
* @deprecated `createLocaleRedirect()` has been removed due to performance
|
|
5
|
+
* issues.
|
|
21
6
|
*/
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const locales = repository.languages.map((language) => {
|
|
28
|
-
return config.localeOverrides?.[language.id] ?? language.id;
|
|
29
|
-
});
|
|
30
|
-
const defaultLocale = locales[0];
|
|
31
|
-
|
|
32
|
-
const { pathname } = config.request.nextUrl;
|
|
33
|
-
const pathnameHasLocale = locales.some(
|
|
34
|
-
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`,
|
|
7
|
+
export function createLocaleRedirect() {
|
|
8
|
+
throw new Error(
|
|
9
|
+
`createLocaleRedirect() has been removed due to performance issues. See ${devMsg(
|
|
10
|
+
"replace-createLocaleRedirect",
|
|
11
|
+
)} for more details.`,
|
|
35
12
|
);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const headers = {
|
|
44
|
-
"accept-language":
|
|
45
|
-
config.request.headers.get("accept-language") ?? undefined,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
if (headers["accept-language"]) {
|
|
49
|
-
const languages = new Negotiator({ headers }).languages();
|
|
50
|
-
locale = match(languages, locales, defaultLocale);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (locale === defaultLocale && config.omitDefaultLocale) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
config.request.nextUrl.pathname = `/${locale}${pathname}`;
|
|
58
|
-
|
|
59
|
-
return Response.redirect(config.request.nextUrl as URL);
|
|
60
|
-
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated `createLocaleRedirect()` has been removed due to performance
|
|
16
|
+
* issues.
|
|
17
|
+
*/
|
|
18
|
+
export type CreateLocaleRedirectConfig = never;
|
|
@@ -1,125 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { PreviewData } from "next";
|
|
3
|
-
import * as prismic from "@prismicio/client";
|
|
1
|
+
import { type Client, cookie as prismicCookie } from "@prismicio/client";
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Configuration for `enableAutoPreviews`.
|
|
9
|
-
*
|
|
10
|
-
* @typeParam TPreviewData - Next.js preview data object.
|
|
11
|
-
*/
|
|
12
|
-
export type EnableAutoPreviewsConfig<
|
|
13
|
-
TPreviewData extends PreviewData = PreviewData,
|
|
14
|
-
> = {
|
|
15
|
-
/**
|
|
16
|
-
* Prismic client with which automatic previews will be enabled.
|
|
17
|
-
*/
|
|
3
|
+
/** Configuration for `enableAutoPreviews`. */
|
|
4
|
+
export type EnableAutoPreviewsConfig = {
|
|
5
|
+
/** Prismic client with which automatic previews will be enabled. */
|
|
18
6
|
// `Pick` is used to use the smallest possible subset of
|
|
19
7
|
// `prismic.Client`. Doing this reduces the surface area for breaking
|
|
20
8
|
// type changes.
|
|
21
|
-
client: Pick<
|
|
22
|
-
prismic.Client,
|
|
23
|
-
"queryContentFromRef" | "enableAutoPreviewsFromReq"
|
|
24
|
-
>;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* **Only used in the Pages Directory (/pages).**
|
|
28
|
-
*
|
|
29
|
-
* The `previewData` object provided in the `getStaticProps()` or
|
|
30
|
-
* `getServerSideProps()` context object.
|
|
31
|
-
*/
|
|
32
|
-
previewData?: TPreviewData;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* **Only used in the Pages Directory (/pages).**
|
|
36
|
-
*
|
|
37
|
-
* The `req` object from a Next.js API route.
|
|
38
|
-
*
|
|
39
|
-
* @see Next.js API route docs: \<https://nextjs.org/docs/api-routes/introduction\>
|
|
40
|
-
*/
|
|
41
|
-
req?: NextApiRequestLike;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const isPrismicPreviewData = (input: unknown): input is PrismicPreviewData => {
|
|
45
|
-
return typeof input === "object" && input !== null && "ref" in input;
|
|
9
|
+
client: Pick<Client, "queryContentFromRef" | "enableAutoPreviewsFromReq">;
|
|
46
10
|
};
|
|
47
11
|
|
|
48
12
|
/**
|
|
49
13
|
* Configures a Prismic client to automatically query draft content during a
|
|
50
|
-
* preview session.
|
|
51
|
-
* or a Next.js API endpoint request object.
|
|
14
|
+
* preview session.
|
|
52
15
|
*
|
|
53
16
|
* @param config - Configuration for the function.
|
|
54
17
|
*/
|
|
55
|
-
export
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
// directory
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
18
|
+
export function enableAutoPreviews(config: EnableAutoPreviewsConfig): void {
|
|
19
|
+
// We use a function value so the cookie is checked on every
|
|
20
|
+
// request. We don't have a static value to read from.
|
|
21
|
+
config.client.queryContentFromRef(async () => {
|
|
22
|
+
// Need this to avoid the following Next.js build-time error:
|
|
23
|
+
// You're importing a component that needs next/headers. That only works
|
|
24
|
+
// in a Server Component which is not supported in the pages/ directory.
|
|
25
|
+
const { cookies, draftMode } = await import("next/headers");
|
|
26
|
+
|
|
27
|
+
let isDraftModeEnabled = false;
|
|
28
|
+
try {
|
|
29
|
+
isDraftModeEnabled = (await draftMode()).isEnabled;
|
|
30
|
+
} catch {
|
|
31
|
+
// `draftMode()` may have been called in a palce that
|
|
32
|
+
// does not have access to its async storage. This
|
|
33
|
+
// occurs in places like `generateStaticParams()`. We
|
|
34
|
+
// can ignore this case.
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (!isDraftModeEnabled) {
|
|
38
|
+
return;
|
|
65
39
|
}
|
|
66
|
-
} else if ("req" in config && config.req) {
|
|
67
|
-
// Assume we are in an API Route (`pages` directory).
|
|
68
|
-
|
|
69
|
-
config.client.enableAutoPreviewsFromReq(config.req);
|
|
70
|
-
} else {
|
|
71
|
-
// Assume we are in App Router (`app` directory) OR
|
|
72
|
-
// `getStaticProps()`/`getServerSideProps()` with an inactive
|
|
73
|
-
// Preview Mode (`pages` directory).
|
|
74
|
-
|
|
75
|
-
// We use a function value so the cookie is checked on every
|
|
76
|
-
// request. We don't have a static value to read from.
|
|
77
|
-
config.client.queryContentFromRef(() => {
|
|
78
|
-
let isDraftModeEnabled = false;
|
|
79
|
-
try {
|
|
80
|
-
isDraftModeEnabled = draftMode().isEnabled;
|
|
81
|
-
} catch {
|
|
82
|
-
// This catch block may be reached if
|
|
83
|
-
// `draftMode()` is called in a place that does
|
|
84
|
-
// not have access to its async storage. We can
|
|
85
|
-
// ignore this case.
|
|
86
|
-
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (!isDraftModeEnabled) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
40
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// We are probably in `getStaticProps()` or
|
|
99
|
-
// `getServerSideProps()` with inactive Preview
|
|
100
|
-
// Mode where `cookies()` does not work. We
|
|
101
|
-
// don't need to do any preview handling.
|
|
41
|
+
const cookie = (await cookies()).get(prismicCookie.preview)?.value;
|
|
42
|
+
if (!cookie) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
102
45
|
|
|
103
|
-
|
|
104
|
-
|
|
46
|
+
const isActiveCookie = cookie.includes("websitePreviewId=");
|
|
47
|
+
if (!isActiveCookie) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
105
50
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// {
|
|
110
|
-
// "_tracker": "abc123"
|
|
111
|
-
// }
|
|
112
|
-
//
|
|
113
|
-
// An active cookie looks like this (URL encoded):
|
|
114
|
-
// {
|
|
115
|
-
// "_tracker": "abc123",
|
|
116
|
-
// "example-prismic-repo.prismic.io": {
|
|
117
|
-
// preview: "https://example-prismic-repo.prismic.io/previews/abc:123?websitePreviewId=xyz"
|
|
118
|
-
// }
|
|
119
|
-
// }
|
|
120
|
-
if (cookie && /\.prismic\.io/.test(cookie)) {
|
|
121
|
-
return cookie;
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
};
|
|
51
|
+
return cookie;
|
|
52
|
+
});
|
|
53
|
+
}
|
package/src/exitPreview.ts
CHANGED
|
@@ -1,92 +1,31 @@
|
|
|
1
|
-
import { draftMode } from "next/headers";
|
|
2
|
-
|
|
3
|
-
import { NextApiRequestLike, NextApiResponseLike } from "./types";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @deprecated Use `ExitPreviewAPIRouteConfig` instead when `exitPreview()` is
|
|
7
|
-
* used in a Pages Router API endpoint. `exitPreview()` does not require any
|
|
8
|
-
* configuration when used in an App Router Route Handler.
|
|
9
|
-
*/
|
|
10
|
-
export type ExitPreviewConfig = ExitPreviewAPIRouteConfig;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Configuration for `exitPreview()` when used in a Pages Router API route.
|
|
14
|
-
*/
|
|
15
|
-
export type ExitPreviewAPIRouteConfig = {
|
|
16
|
-
/**
|
|
17
|
-
* **Only use this parameter in the Pages Directory (/pages).**
|
|
18
|
-
*
|
|
19
|
-
* The `req` object from a Next.js API route.
|
|
20
|
-
*
|
|
21
|
-
* @see Next.js API route docs: \<https://nextjs.org/docs/api-routes/introduction\>
|
|
22
|
-
*/
|
|
23
|
-
req?: NextApiRequestLike;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* **Only use this parameter in the Pages Directory (/pages).**
|
|
27
|
-
*
|
|
28
|
-
* The `res` object from a Next.js API route.
|
|
29
|
-
*
|
|
30
|
-
* @see Next.js API route docs: \<https://nextjs.org/docs/api-routes/introduction\>
|
|
31
|
-
*/
|
|
32
|
-
res?: NextApiResponseLike;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
1
|
/**
|
|
36
2
|
* Ends a Prismic preview session within a Next.js app. This function should be
|
|
37
|
-
* used in a Router Handler
|
|
38
|
-
* the App Router or Pages Router.
|
|
3
|
+
* used in a Router Handler.
|
|
39
4
|
*
|
|
40
|
-
* @example
|
|
5
|
+
* @example
|
|
41
6
|
*
|
|
42
7
|
* ```typescript
|
|
43
8
|
* // src/app/api/exit-preview/route.js
|
|
44
9
|
*
|
|
45
10
|
* import { exitPreview } from "@prismicio/next";
|
|
46
11
|
*
|
|
47
|
-
* export function GET() {
|
|
48
|
-
* return exitPreview();
|
|
49
|
-
* }
|
|
50
|
-
* ```
|
|
51
|
-
*
|
|
52
|
-
* @example Usage within a Pages Router API Route.
|
|
53
|
-
*
|
|
54
|
-
* ```typescript
|
|
55
|
-
* // src/pages/api/exit-preview.js
|
|
56
|
-
*
|
|
57
|
-
* import { exitPreview } from "@prismicio/next";
|
|
58
|
-
*
|
|
59
|
-
* export default function handler(req, res) {
|
|
60
|
-
* exitPreview({ req, res });
|
|
12
|
+
* export async function GET() {
|
|
13
|
+
* return await exitPreview();
|
|
61
14
|
* }
|
|
62
15
|
* ```
|
|
63
16
|
*/
|
|
64
|
-
export function exitPreview(): Response
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return;
|
|
80
|
-
} else {
|
|
81
|
-
// Assume Draft Mode is being used.
|
|
82
|
-
|
|
83
|
-
draftMode().disable();
|
|
84
|
-
|
|
85
|
-
// `Cache-Control` header is used to prevent CDN-level caching.
|
|
86
|
-
return new Response(JSON.stringify({ success: true }), {
|
|
87
|
-
headers: {
|
|
88
|
-
"Cache-Control": "no-store",
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
}
|
|
17
|
+
export async function exitPreview(): Promise<Response> {
|
|
18
|
+
// Need this to avoid the following Next.js build-time error:
|
|
19
|
+
// You're importing a component that needs next/headers. That only works
|
|
20
|
+
// in a Server Component which is not supported in the pages/ directory.
|
|
21
|
+
const { draftMode } = await import("next/headers");
|
|
22
|
+
|
|
23
|
+
(await draftMode()).disable();
|
|
24
|
+
|
|
25
|
+
// `Cache-Control` header is used to prevent CDN-level caching.
|
|
26
|
+
return new Response(JSON.stringify({ success: true }), {
|
|
27
|
+
headers: {
|
|
28
|
+
"Cache-Control": "no-store",
|
|
29
|
+
},
|
|
30
|
+
});
|
|
92
31
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,34 +1,23 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type { SetPreviewDataConfig } from "./setPreviewData";
|
|
1
|
+
export { exitPreview } from "./exitPreview.js";
|
|
3
2
|
|
|
4
|
-
export {
|
|
5
|
-
export type {
|
|
6
|
-
ExitPreviewConfig,
|
|
7
|
-
ExitPreviewAPIRouteConfig,
|
|
8
|
-
} from "./exitPreview";
|
|
3
|
+
export { PrismicPreview } from "./PrismicPreview.js";
|
|
4
|
+
export type { PrismicPreviewProps } from "./PrismicPreview.js";
|
|
9
5
|
|
|
10
|
-
export {
|
|
11
|
-
export type {
|
|
6
|
+
export { PrismicNextLink } from "./PrismicNextLink.js";
|
|
7
|
+
export type { PrismicNextLinkProps } from "./PrismicNextLink.js";
|
|
12
8
|
|
|
13
|
-
export {
|
|
14
|
-
export type {
|
|
9
|
+
export { enableAutoPreviews } from "./enableAutoPreviews.js";
|
|
10
|
+
export type { EnableAutoPreviewsConfig } from "./enableAutoPreviews.js";
|
|
15
11
|
|
|
16
|
-
export {
|
|
17
|
-
export type {
|
|
12
|
+
export { redirectToPreviewURL } from "./redirectToPreviewURL.js";
|
|
13
|
+
export type { RedirectToPreviewURLConfig } from "./redirectToPreviewURL.js";
|
|
18
14
|
|
|
19
|
-
export {
|
|
20
|
-
export type {
|
|
21
|
-
RedirectToPreviewURLConfig,
|
|
22
|
-
RedirectToPreviewURLRouteHandlerConfig,
|
|
23
|
-
RedirectToPreviewURLAPIEndpointConfig,
|
|
24
|
-
} from "./redirectToPreviewURL";
|
|
15
|
+
export { PrismicNextImage } from "./PrismicNextImage.js";
|
|
16
|
+
export type { PrismicNextImageProps } from "./PrismicNextImage.js";
|
|
25
17
|
|
|
26
|
-
export {
|
|
27
|
-
export type { CreateLocaleRedirectConfig } from "./createLocaleRedirect";
|
|
18
|
+
export { imgixLoader } from "./imgixLoader.js";
|
|
28
19
|
|
|
29
|
-
export {
|
|
30
|
-
export type { PrismicNextImageProps } from "./PrismicNextImage";
|
|
20
|
+
export type { CreateClientConfig } from "./types.js";
|
|
31
21
|
|
|
32
|
-
export {
|
|
33
|
-
|
|
34
|
-
export type { CreateClientConfig, PrismicPreviewData } from "./types";
|
|
22
|
+
export { createLocaleRedirect } from "./createLocaleRedirect.js";
|
|
23
|
+
export type { CreateLocaleRedirectConfig } from "./createLocaleRedirect.js";
|
package/src/lib/devMsg.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { version } from "../../package.json";
|
|
|
7
7
|
*
|
|
8
8
|
* ```ts
|
|
9
9
|
* devMsg("missing-param");
|
|
10
|
-
* // => "https://prismic.dev/msg/next/v1.2.3/missing-param
|
|
10
|
+
* // => "https://prismic.dev/msg/next/v1.2.3/missing-param"
|
|
11
11
|
* ```
|
|
12
12
|
*
|
|
13
13
|
* @param slug - Slug for the message. This corresponds to a Markdown file in
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { type ReactNode, useEffect, JSX } from "react";
|
|
2
|
+
import { useRouter } from "next/router";
|
|
3
|
+
import Script from "next/script";
|
|
4
|
+
import { getToolbarSrc, cookie as prismicCookie } from "@prismicio/client";
|
|
5
|
+
|
|
6
|
+
/** Props for `<PrismicPreview>`. */
|
|
7
|
+
export type PrismicPreviewProps = {
|
|
8
|
+
/**
|
|
9
|
+
* The name of your Prismic repository. A Prismic Toolbar will be registered
|
|
10
|
+
* using this repository.
|
|
11
|
+
*/
|
|
12
|
+
repositoryName: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The URL of your app's Prismic preview endpoint (default: `/api/preview`).
|
|
16
|
+
* This URL will be fetched on preview update events.
|
|
17
|
+
*/
|
|
18
|
+
updatePreviewURL?: string;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The URL of your app's exit preview endpoint (default: `/api/exit-preview`).
|
|
22
|
+
* This URL will be fetched on preview exit events.
|
|
23
|
+
*/
|
|
24
|
+
exitPreviewURL?: string;
|
|
25
|
+
|
|
26
|
+
/** Children to render adjacent to the Prismic Toolbar. */
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* React component that sets up Prismic Previews using the Prismic Toolbar. When
|
|
32
|
+
* the Prismic Toolbar send events to the browser, such as on preview updates
|
|
33
|
+
* and exiting, this component will automatically refresh the page with the
|
|
34
|
+
* changes.
|
|
35
|
+
*
|
|
36
|
+
* This component can be wrapped around your app or added anywhere in your app's
|
|
37
|
+
* tree. It must be rendered on every page.
|
|
38
|
+
*/
|
|
39
|
+
export function PrismicPreview(props: PrismicPreviewProps): JSX.Element {
|
|
40
|
+
const {
|
|
41
|
+
repositoryName,
|
|
42
|
+
updatePreviewURL = "/api/preview",
|
|
43
|
+
exitPreviewURL = "/api/exit-preview",
|
|
44
|
+
children,
|
|
45
|
+
} = props;
|
|
46
|
+
|
|
47
|
+
const router = useRouter();
|
|
48
|
+
|
|
49
|
+
const toolbarSrc = getToolbarSrc(repositoryName);
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
|
|
54
|
+
window.addEventListener("prismicPreviewUpdate", onUpdate, {
|
|
55
|
+
signal: controller.signal,
|
|
56
|
+
});
|
|
57
|
+
window.addEventListener("prismicPreviewEnd", onEnd, {
|
|
58
|
+
signal: controller.signal,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Start the preview for preview share links. Previews from
|
|
62
|
+
// share links do not go to the `updatePreviewURL` like a normal
|
|
63
|
+
// preview.
|
|
64
|
+
//
|
|
65
|
+
// We check that the current URL is a descendant of the base
|
|
66
|
+
// path to prevent infinite refrehes.
|
|
67
|
+
if (
|
|
68
|
+
window.location.href.startsWith(
|
|
69
|
+
window.location.origin + router.basePath,
|
|
70
|
+
) &&
|
|
71
|
+
getPreviewCookieRepositoryName() === repositoryName &&
|
|
72
|
+
!router.isPreview
|
|
73
|
+
) {
|
|
74
|
+
start();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function onEnd(event: Event) {
|
|
78
|
+
event.preventDefault();
|
|
79
|
+
fetch(router.basePath + exitPreviewURL, { signal: controller.signal })
|
|
80
|
+
.then((res) => {
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
console.error(
|
|
83
|
+
`[<PrismicPreview>] Failed to exit Preview Mode using the "${exitPreviewURL}" API endpoint. Does it exist?`,
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
refresh();
|
|
90
|
+
})
|
|
91
|
+
.catch(() => {});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function onUpdate(event: Event) {
|
|
95
|
+
event.preventDefault();
|
|
96
|
+
start();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function start() {
|
|
100
|
+
// We check `opaqueredirect` because we don't care if
|
|
101
|
+
// the redirect was successful or not. As long as it
|
|
102
|
+
// redirects, we know the endpoint exists and at least
|
|
103
|
+
// attempted to set preview data.
|
|
104
|
+
fetch(router.basePath + updatePreviewURL, {
|
|
105
|
+
redirect: "manual",
|
|
106
|
+
signal: controller.signal,
|
|
107
|
+
})
|
|
108
|
+
.then((res) => {
|
|
109
|
+
if (res.type !== "opaqueredirect") {
|
|
110
|
+
console.error(
|
|
111
|
+
`[<PrismicPreview>] Failed to start or update the preview using "${updatePreviewURL}". Does it exist?`,
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
refresh();
|
|
118
|
+
})
|
|
119
|
+
.catch(() => {});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function refresh() {
|
|
123
|
+
router.replace(router.asPath, undefined, { scroll: false });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return () => controller.abort();
|
|
127
|
+
}, [exitPreviewURL, updatePreviewURL, repositoryName, router]);
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<>
|
|
131
|
+
{children}
|
|
132
|
+
<Script src={toolbarSrc} strategy="lazyOnload" />
|
|
133
|
+
</>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function getPreviewCookieRepositoryName() {
|
|
138
|
+
const cookie = window.document.cookie
|
|
139
|
+
.split("; ")
|
|
140
|
+
.find((row) => row.startsWith(`${prismicCookie.preview}=`))
|
|
141
|
+
?.split("=")[1];
|
|
142
|
+
|
|
143
|
+
return (decodeURIComponent(cookie ?? "").match(/"([^"]+)\.prismic\.io"/) ||
|
|
144
|
+
[])[1];
|
|
145
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { PreviewData } from "next";
|
|
2
|
+
import type { Client } from "@prismicio/client";
|
|
3
|
+
|
|
4
|
+
import type { NextApiRequestLike } from "./types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Configuration for `enableAutoPreviews`.
|
|
8
|
+
*
|
|
9
|
+
* @typeParam TPreviewData - Next.js preview data object.
|
|
10
|
+
*/
|
|
11
|
+
export type EnableAutoPreviewsConfig = {
|
|
12
|
+
/** Prismic client with which automatic previews will be enabled. */
|
|
13
|
+
// `Pick` is used to use the smallest possible subset of
|
|
14
|
+
// `prismic.Client`. Doing this reduces the surface area for breaking
|
|
15
|
+
// type changes.
|
|
16
|
+
client: Pick<Client, "queryContentFromRef" | "enableAutoPreviewsFromReq">;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The `previewData` object provided in the `getStaticProps()` or
|
|
20
|
+
* `getServerSideProps()` context object.
|
|
21
|
+
*/
|
|
22
|
+
previewData?: PreviewData;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The `req` object from a Next.js API route.
|
|
26
|
+
*
|
|
27
|
+
* @see Next.js API route docs: \<https://nextjs.org/docs/api-routes/introduction\>
|
|
28
|
+
*/
|
|
29
|
+
req?: NextApiRequestLike;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Configures a Prismic client to automatically query draft content during a
|
|
34
|
+
* preview session. It either takes in a Next.js `getStaticProps` context object
|
|
35
|
+
* or a Next.js API endpoint request object.
|
|
36
|
+
*
|
|
37
|
+
* @param config - Configuration for the function.
|
|
38
|
+
*/
|
|
39
|
+
export function enableAutoPreviews(config: EnableAutoPreviewsConfig): void {
|
|
40
|
+
if ("previewData" in config && config.previewData) {
|
|
41
|
+
// Assume we are in `getStaticProps()` or
|
|
42
|
+
// `getServerSideProps()` with active Preview Mode.
|
|
43
|
+
|
|
44
|
+
if (isPrismicPreviewData(config.previewData)) {
|
|
45
|
+
config.client.queryContentFromRef(config.previewData.ref);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if ("req" in config && config.req) {
|
|
52
|
+
// Assume we are in an API Route.
|
|
53
|
+
|
|
54
|
+
config.client.enableAutoPreviewsFromReq(config.req);
|
|
55
|
+
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function isPrismicPreviewData(input: unknown): input is { ref: string } {
|
|
61
|
+
return typeof input === "object" && input !== null && "ref" in input;
|
|
62
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { NextApiRequestLike, NextApiResponseLike } from "./types.js";
|
|
2
|
+
|
|
3
|
+
/** Configuration for `exitPreview()`. */
|
|
4
|
+
export type ExitPreviewAPIRouteConfig = {
|
|
5
|
+
/**
|
|
6
|
+
* The `req` object from a Next.js API route.
|
|
7
|
+
*
|
|
8
|
+
* @see Next.js API route docs: \<https://nextjs.org/docs/api-routes/introduction\>
|
|
9
|
+
*/
|
|
10
|
+
req?: NextApiRequestLike;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The `res` object from a Next.js API route.
|
|
14
|
+
*
|
|
15
|
+
* @see Next.js API route docs: \<https://nextjs.org/docs/api-routes/introduction\>
|
|
16
|
+
*/
|
|
17
|
+
res: NextApiResponseLike;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Ends a Prismic preview session within a Next.js app. This function should be
|
|
22
|
+
* used in an API route.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
*
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // src/pages/api/exit-preview.js
|
|
28
|
+
*
|
|
29
|
+
* import { exitPreview } from "@prismicio/next";
|
|
30
|
+
*
|
|
31
|
+
* export default function handler(_req, res) {
|
|
32
|
+
* return exitPreview({ res });
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function exitPreview(config: ExitPreviewAPIRouteConfig): void {
|
|
37
|
+
config.res.clearPreviewData();
|
|
38
|
+
|
|
39
|
+
// `Cache-Control` header is used to prevent CDN-level caching.
|
|
40
|
+
config.res.setHeader("Cache-Control", "no-store");
|
|
41
|
+
|
|
42
|
+
config.res.json({ success: true });
|
|
43
|
+
|
|
44
|
+
return;
|
|
45
|
+
}
|