@prismicio/next 0.0.1 → 0.0.5

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 ADDED
@@ -0,0 +1,90 @@
1
+ # @prismicio/next
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+ [![Github Actions CI][github-actions-ci-src]][github-actions-ci-href]
6
+ [![Codecov][codecov-src]][codecov-href]
7
+ [![Conventional Commits][conventional-commits-src]][conventional-commits-href]
8
+ [![License][license-src]][license-href]
9
+
10
+ > ⚠ This project is in an experimental state and therefore primarily meant to be used by Prismic kits. Use it at your own risks or stay tuned for the official release!
11
+
12
+ <!-- TODO: Replacing link to Prismic with [Prismic][prismic] is useful here -->
13
+
14
+ A Next.js Integration with Prismic that makes it easier to take advantage of Next.js features.
15
+
16
+ - 🎥 &nbsp;Easily set up Prismic Previews;
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm install @prismicio/next
22
+ ```
23
+
24
+ ## Documentation
25
+
26
+ To discover what's new on this package check out [the changelog][changelog]. For full documentation, visit the [official Prismic documentation][prismic-docs].
27
+
28
+ ## Contributing
29
+
30
+ Whether you're helping us fix bugs, improve the docs, or spread the word, we'd love to have you as part of the Prismic developer community!
31
+
32
+ **Asking a question**: [Open a new topic][forum-question] on our community forum explaining what you want to achieve / your question. Our support team will get back to you shortly.
33
+
34
+ **Reporting a bug**: [Open an issue][repo-bug-report] explaining your application's setup and the bug you're encountering.
35
+
36
+ **Suggesting an improvement**: [Open an issue][repo-feature-request] explaining your improvement or feature so we can discuss and learn more.
37
+
38
+ **Submitting code changes**: For small fixes, feel free to [open a pull request][repo-pull-requests] with a description of your changes. For large changes, please first [open an issue][repo-feature-request] so we can discuss if and how the changes should be implemented.
39
+
40
+ For more clarity on this project and its structure you can also check out the detailed [CONTRIBUTING.md][contributing] document.
41
+
42
+ ## License
43
+
44
+ ```
45
+ Copyright 2013-2021 Prismic <contact@prismic.io> (https://prismic.io)
46
+
47
+ Licensed under the Apache License, Version 2.0 (the "License");
48
+ you may not use this file except in compliance with the License.
49
+ You may obtain a copy of the License at
50
+
51
+ http://www.apache.org/licenses/LICENSE-2.0
52
+
53
+ Unless required by applicable law or agreed to in writing, software
54
+ distributed under the License is distributed on an "AS IS" BASIS,
55
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
56
+ See the License for the specific language governing permissions and
57
+ limitations under the License.
58
+ ```
59
+
60
+ <!-- Links -->
61
+
62
+ [prismic]: https://prismic.io
63
+
64
+ <!-- TODO: Replace link with a more useful one if available -->
65
+
66
+ [prismic-docs]: https://prismic.io/docs
67
+ [changelog]: ./CHANGELOG.md
68
+ [contributing]: ./CONTRIBUTING.md
69
+
70
+ <!-- TODO: Replace link with a more useful one if available -->
71
+
72
+ [forum-question]: https://community.prismic.io
73
+ [repo-bug-report]: https://github.com/prismicio/prismic-next/issues/new?assignees=&labels=bug&template=bug_report.md&title=
74
+ [repo-feature-request]: https://github.com/prismicio/prismic-next/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=
75
+ [repo-pull-requests]: https://github.com/prismicio/prismic-next/pulls
76
+
77
+ <!-- Badges -->
78
+
79
+ [npm-version-src]: https://img.shields.io/npm/v/@prismicio/next/latest.svg
80
+ [npm-version-href]: https://npmjs.com/package/@prismicio/next
81
+ [npm-downloads-src]: https://img.shields.io/npm/dm/@prismicio/next.svg
82
+ [npm-downloads-href]: https://npmjs.com/package/@prismicio/next
83
+ [github-actions-ci-src]: https://github.com/prismicio/prismic-next/workflows/ci/badge.svg
84
+ [github-actions-ci-href]: https://github.com/prismicio/prismic-next/actions?query=workflow%3Aci
85
+ [codecov-src]: https://img.shields.io/codecov/c/github/prismicio/prismic-next.svg
86
+ [codecov-href]: https://codecov.io/gh/prismicio/prismic-next
87
+ [conventional-commits-src]: https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg
88
+ [conventional-commits-href]: https://conventionalcommits.org
89
+ [license-src]: https://img.shields.io/npm/l/@prismicio/next.svg
90
+ [license-href]: https://npmjs.com/package/@prismicio/next
package/dist/index.cjs CHANGED
@@ -2,19 +2,40 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ const prismic = require('@prismicio/client');
5
6
  const React = require('react');
6
7
  const react = require('@prismicio/react');
8
+ const router = require('next/router');
7
9
 
8
10
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
11
 
12
+ function _interopNamespace(e) {
13
+ if (e && e.__esModule) return e;
14
+ const n = Object.create(null);
15
+ if (e) {
16
+ for (const k in e) {
17
+ if (k !== 'default') {
18
+ const d = Object.getOwnPropertyDescriptor(e, k);
19
+ Object.defineProperty(n, k, d.get ? d : {
20
+ enumerable: true,
21
+ get: function () { return e[k]; }
22
+ });
23
+ }
24
+ }
25
+ }
26
+ n["default"] = e;
27
+ return Object.freeze(n);
28
+ }
29
+
30
+ const prismic__namespace = /*#__PURE__*/_interopNamespace(prismic);
10
31
  const React__default = /*#__PURE__*/_interopDefaultLegacy(React);
11
32
 
12
33
  async function setPreviewData({
13
34
  req,
14
35
  res
15
36
  }) {
16
- if (req.query.token) {
17
- const { token: ref } = req.query;
37
+ const ref = req.query.token || req.cookies[prismic__namespace.cookie.preview];
38
+ if (ref) {
18
39
  res.setPreviewData({ ref });
19
40
  }
20
41
  }
@@ -32,6 +53,50 @@ function exitPreview(config) {
32
53
  config.res.redirect("/");
33
54
  }
34
55
 
56
+ const readValue = (value) => {
57
+ return value.replace(/%3B/g, ";");
58
+ };
59
+ const parse = (cookieString) => {
60
+ const result = {};
61
+ const cookies = cookieString.split("; ");
62
+ for (const cookie of cookies) {
63
+ const parts = cookie.split("=");
64
+ const value = parts.slice(1).join("=");
65
+ const name = readValue(parts[0]).replace(/%3D/g, "=");
66
+ result[name] = readValue(value);
67
+ }
68
+ return result;
69
+ };
70
+ const getAll = (cookieStore) => parse(cookieStore);
71
+ const getCookie = (name, cookieStore) => getAll(cookieStore)[name];
72
+
73
+ const extractFirstSubdomain = (host) => host.split(".")[0];
74
+ const extractRepositoryNameFromObjectRef = (previewRef) => {
75
+ try {
76
+ const parsed = JSON.parse(decodeURIComponent(previewRef));
77
+ const keys = Object.keys(parsed);
78
+ const domainKey = keys.find((key) => /\.prismic\.io$/.test(key));
79
+ if (domainKey) {
80
+ return extractFirstSubdomain(domainKey);
81
+ } else {
82
+ return void 0;
83
+ }
84
+ } catch (e) {
85
+ return void 0;
86
+ }
87
+ };
88
+ const extractRepositoryNameFromURLRef = (previewRef) => {
89
+ try {
90
+ const url = new URL(previewRef);
91
+ return extractFirstSubdomain(url.host);
92
+ } catch (e) {
93
+ return void 0;
94
+ }
95
+ };
96
+ const extractPreviewRefRepositoryName = (previewRef) => {
97
+ return extractRepositoryNameFromObjectRef(previewRef) || extractRepositoryNameFromURLRef(previewRef);
98
+ };
99
+
35
100
  const isPrismicUpdateToolbarEvent = (event) => {
36
101
  return "detail" in event && typeof event.detail.ref === "string";
37
102
  };
@@ -41,27 +106,36 @@ function PrismicPreview({
41
106
  updatePreviewURL = "/api/preview",
42
107
  exitPreviewURL = "/api/exit-preview"
43
108
  }) {
109
+ const router$1 = router.useRouter();
44
110
  React.useEffect(() => {
45
- const prismicPreviewUpdate = async (event) => {
111
+ const previewRefRepositoryName = extractPreviewRefRepositoryName(getCookie("io.prismic.preview", globalThis.document.cookie));
112
+ const startPreviewIfLoadedFromSharedLink = async () => {
113
+ if (previewRefRepositoryName === repositoryName && !router$1.isPreview) {
114
+ await fetch(updatePreviewURL);
115
+ window.location.reload();
116
+ }
117
+ };
118
+ startPreviewIfLoadedFromSharedLink();
119
+ const handlePrismicPreviewUpdate = async (event) => {
46
120
  if (isPrismicUpdateToolbarEvent(event)) {
47
121
  event.preventDefault();
48
- await fetch(`${updatePreviewURL}?token=${event.detail.ref}`);
122
+ await fetch(updatePreviewURL);
49
123
  window.location.reload();
50
124
  }
51
125
  };
52
- const prismicPreviewEnd = async (event) => {
126
+ const handlePrismicPreviewEnd = async (event) => {
53
127
  event.preventDefault();
54
128
  await fetch(exitPreviewURL);
55
129
  window.location.reload();
56
130
  };
57
131
  if (window) {
58
- window.addEventListener("prismicPreviewUpdate", prismicPreviewUpdate);
59
- window.addEventListener("prismicPreviewEnd", prismicPreviewEnd);
132
+ window.addEventListener("prismicPreviewUpdate", handlePrismicPreviewUpdate);
133
+ window.addEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
60
134
  }
61
135
  return () => {
62
136
  if (window) {
63
- window.removeEventListener("prismicPreviewUpdate", prismicPreviewUpdate);
64
- window.removeEventListener("prismicPreviewEnd", prismicPreviewEnd);
137
+ window.removeEventListener("prismicPreviewUpdate", handlePrismicPreviewUpdate);
138
+ window.removeEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
65
139
  }
66
140
  };
67
141
  }, []);
@@ -74,8 +148,8 @@ const isPrismicNextPreviewData = (previewData) => {
74
148
  return typeof previewData === "object" && "ref" in previewData;
75
149
  };
76
150
  const enableAutoPreviews = (config) => {
77
- if ("context" in config && config.context) {
78
- const previewData = config.context.previewData;
151
+ if ("previewData" in config && config.previewData) {
152
+ const { previewData } = config;
79
153
  if (isPrismicNextPreviewData(previewData) && previewData.ref) {
80
154
  config.client.queryContentFromRef(previewData.ref);
81
155
  }
@@ -101,6 +175,7 @@ async function redirectToPreviewURL({
101
175
  previewToken: token
102
176
  });
103
177
  res.redirect(previewUrl);
178
+ return;
104
179
  }
105
180
  res.redirect(defaultURL);
106
181
  }
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { NextApiRequest, NextApiResponse, PreviewData } from 'next';
2
2
  import { Client, HttpRequestLike } from '@prismicio/client';
3
- import { LinkResolverFunction } from '@prismicio/helpers';
4
3
  import React from 'react';
4
+ import { LinkResolverFunction } from '@prismicio/helpers';
5
5
 
6
6
  /**
7
7
  * Configuration for `setPreviewData`.
@@ -15,6 +15,7 @@ declare type SetPreviewDataConfig = {
15
15
  */
16
16
  req: {
17
17
  query: NextApiRequest["query"];
18
+ cookies: NextApiRequest["cookies"];
18
19
  };
19
20
  /**
20
21
  * The `res` object from a Next.js API route. This is given as a parameter to
@@ -31,70 +32,6 @@ declare type SetPreviewDataConfig = {
31
32
  */
32
33
  declare function setPreviewData({ req, res, }: SetPreviewDataConfig): Promise<void>;
33
34
 
34
- /**
35
- * Next.js context object from APIs supporting Preview Mode. This includes the
36
- * context object from `getStaticProps` and `getServerSideProps`.
37
- */
38
- declare type NextContextLike<TPreviewData extends PreviewData = PreviewData> = {
39
- previewData?: TPreviewData;
40
- };
41
- /**
42
- * Configuration for creating a Prismic client with automatic preview support in
43
- * Next.js apps.
44
- */
45
- declare type CreateClientConfig = {
46
- /**
47
- * A Next.js context object (such as the context object from `getStaticProps`
48
- * or `getServerSideProps`).
49
- *
50
- * Pass a `context` when using outside a Next.js API endpoint.
51
- */
52
- context?: NextContextLike;
53
- /**
54
- * A Next.js API endpoint request object.
55
- *
56
- * Pass a `req` object when using in a Next.js API endpoint.
57
- */
58
- req?: NextApiRequest;
59
- };
60
- /**
61
- * Preview config for enabling previews with redirectToPreviewURL
62
- */
63
- declare type PreviewConfig = {
64
- /**
65
- * The `req` object from a Next.js API route. This is given as a parameter to
66
- * the API route.
67
- *
68
- * @see Next.js API route docs: {@link https://nextjs.org/docs/api-routes/introduction}
69
- */
70
- req: {
71
- query: NextApiRequest["query"];
72
- };
73
- /**
74
- * The `res` object from a Next.js API route. This is given as a parameter to
75
- * the API route.
76
- *
77
- * @see Next.js API route docs: {@link https://nextjs.org/docs/api-routes/introduction}
78
- */
79
- res: {
80
- redirect: NextApiResponse["redirect"];
81
- };
82
- /**
83
- * The Prismic client configured for the preview session's repository.
84
- */
85
- client: Client;
86
- /**
87
- * A Link Resolver used to resolve the previewed document's URL.
88
- *
89
- * @see To learn more about Link Resolver: {@link https://prismic.io/docs/core-concepts/link-resolver-route-resolver}
90
- */
91
- linkResolver?: LinkResolverFunction;
92
- /**
93
- * The default redirect URL if a URL cannot be determined for the previewed document.
94
- */
95
- defaultURL?: string;
96
- };
97
-
98
35
  /**
99
36
  * Configuration for `enableAutoPreviews`.
100
37
  *
@@ -113,7 +50,7 @@ declare type EnableAutoPreviewsConfig<TPreviewData extends PreviewData = Preview
113
50
  * Pass a `context` object when using `enableAutoPreviews` outside a
114
51
  * Next.js API endpoint.
115
52
  */
116
- context?: NextContextLike<TPreviewData>;
53
+ previewData?: TPreviewData;
117
54
  } | {
118
55
  /**
119
56
  * A Next.js API endpoint request object.
@@ -129,7 +66,7 @@ declare type EnableAutoPreviewsConfig<TPreviewData extends PreviewData = Preview
129
66
  *
130
67
  * @param config - Configuration for the function.
131
68
  */
132
- declare const enableAutoPreviews: <TPreviewData extends PreviewData = PreviewData>(config: EnableAutoPreviewsConfig<TPreviewData>) => void;
69
+ declare const enableAutoPreviews: <TPreviewData extends PreviewData>(config: EnableAutoPreviewsConfig<TPreviewData>) => void;
133
70
 
134
71
  /**
135
72
  * Configuration for `exitPreview`.
@@ -203,4 +140,61 @@ declare function PrismicPreview({ repositoryName, children, updatePreviewURL, ex
203
140
  */
204
141
  declare function redirectToPreviewURL({ req, res, client, linkResolver, defaultURL, }: PreviewConfig): Promise<void>;
205
142
 
206
- export { CreateClientConfig, EnableAutoPreviewsConfig, ExitPreviewConfig as ExitPreviewParams, NextContextLike, PreviewConfig, PrismicPreview, SetPreviewDataConfig, enableAutoPreviews, exitPreview, redirectToPreviewURL, setPreviewData };
143
+ /**
144
+ * Configuration for creating a Prismic client with automatic preview support in
145
+ * Next.js apps.
146
+ */
147
+ declare type CreateClientConfig = {
148
+ /**
149
+ * Preview data coming from Next.js context object. This context object comes
150
+ * from `getStaticProps` or `getServerSideProps`.
151
+ *
152
+ * Pass `previewData` when using outside a Next.js API endpoint.
153
+ */
154
+ previewData?: PreviewData;
155
+ /**
156
+ * A Next.js API endpoint request object.
157
+ *
158
+ * Pass a `req` object when using in a Next.js API endpoint.
159
+ */
160
+ req?: NextApiRequest;
161
+ };
162
+ /**
163
+ * Preview config for enabling previews with redirectToPreviewURL
164
+ */
165
+ declare type PreviewConfig = {
166
+ /**
167
+ * The `req` object from a Next.js API route. This is given as a parameter to
168
+ * the API route.
169
+ *
170
+ * @see Next.js API route docs: {@link https://nextjs.org/docs/api-routes/introduction}
171
+ */
172
+ req: {
173
+ query: NextApiRequest["query"];
174
+ };
175
+ /**
176
+ * The `res` object from a Next.js API route. This is given as a parameter to
177
+ * the API route.
178
+ *
179
+ * @see Next.js API route docs: {@link https://nextjs.org/docs/api-routes/introduction}
180
+ */
181
+ res: {
182
+ redirect: NextApiResponse["redirect"];
183
+ };
184
+ /**
185
+ * The Prismic client configured for the preview session's repository.
186
+ */
187
+ client: Client;
188
+ /**
189
+ * A Link Resolver used to resolve the previewed document's URL.
190
+ *
191
+ * @see To learn more about Link Resolver: {@link https://prismic.io/docs/core-concepts/link-resolver-route-resolver}
192
+ */
193
+ linkResolver?: LinkResolverFunction;
194
+ /**
195
+ * The default redirect URL if a URL cannot be determined for the previewed document.
196
+ */
197
+ defaultURL?: string;
198
+ };
199
+
200
+ export { CreateClientConfig, EnableAutoPreviewsConfig, ExitPreviewConfig as ExitPreviewParams, PreviewConfig, PrismicPreview, SetPreviewDataConfig, enableAutoPreviews, exitPreview, redirectToPreviewURL, setPreviewData };
package/dist/index.mjs CHANGED
@@ -1,12 +1,14 @@
1
+ import * as prismic from '@prismicio/client';
1
2
  import React, { useEffect } from 'react';
2
3
  import { PrismicToolbar } from '@prismicio/react';
4
+ import { useRouter } from 'next/router';
3
5
 
4
6
  async function setPreviewData({
5
7
  req,
6
8
  res
7
9
  }) {
8
- if (req.query.token) {
9
- const { token: ref } = req.query;
10
+ const ref = req.query.token || req.cookies[prismic.cookie.preview];
11
+ if (ref) {
10
12
  res.setPreviewData({ ref });
11
13
  }
12
14
  }
@@ -24,6 +26,50 @@ function exitPreview(config) {
24
26
  config.res.redirect("/");
25
27
  }
26
28
 
29
+ const readValue = (value) => {
30
+ return value.replace(/%3B/g, ";");
31
+ };
32
+ const parse = (cookieString) => {
33
+ const result = {};
34
+ const cookies = cookieString.split("; ");
35
+ for (const cookie of cookies) {
36
+ const parts = cookie.split("=");
37
+ const value = parts.slice(1).join("=");
38
+ const name = readValue(parts[0]).replace(/%3D/g, "=");
39
+ result[name] = readValue(value);
40
+ }
41
+ return result;
42
+ };
43
+ const getAll = (cookieStore) => parse(cookieStore);
44
+ const getCookie = (name, cookieStore) => getAll(cookieStore)[name];
45
+
46
+ const extractFirstSubdomain = (host) => host.split(".")[0];
47
+ const extractRepositoryNameFromObjectRef = (previewRef) => {
48
+ try {
49
+ const parsed = JSON.parse(decodeURIComponent(previewRef));
50
+ const keys = Object.keys(parsed);
51
+ const domainKey = keys.find((key) => /\.prismic\.io$/.test(key));
52
+ if (domainKey) {
53
+ return extractFirstSubdomain(domainKey);
54
+ } else {
55
+ return void 0;
56
+ }
57
+ } catch (e) {
58
+ return void 0;
59
+ }
60
+ };
61
+ const extractRepositoryNameFromURLRef = (previewRef) => {
62
+ try {
63
+ const url = new URL(previewRef);
64
+ return extractFirstSubdomain(url.host);
65
+ } catch (e) {
66
+ return void 0;
67
+ }
68
+ };
69
+ const extractPreviewRefRepositoryName = (previewRef) => {
70
+ return extractRepositoryNameFromObjectRef(previewRef) || extractRepositoryNameFromURLRef(previewRef);
71
+ };
72
+
27
73
  const isPrismicUpdateToolbarEvent = (event) => {
28
74
  return "detail" in event && typeof event.detail.ref === "string";
29
75
  };
@@ -33,27 +79,36 @@ function PrismicPreview({
33
79
  updatePreviewURL = "/api/preview",
34
80
  exitPreviewURL = "/api/exit-preview"
35
81
  }) {
82
+ const router = useRouter();
36
83
  useEffect(() => {
37
- const prismicPreviewUpdate = async (event) => {
84
+ const previewRefRepositoryName = extractPreviewRefRepositoryName(getCookie("io.prismic.preview", globalThis.document.cookie));
85
+ const startPreviewIfLoadedFromSharedLink = async () => {
86
+ if (previewRefRepositoryName === repositoryName && !router.isPreview) {
87
+ await fetch(updatePreviewURL);
88
+ window.location.reload();
89
+ }
90
+ };
91
+ startPreviewIfLoadedFromSharedLink();
92
+ const handlePrismicPreviewUpdate = async (event) => {
38
93
  if (isPrismicUpdateToolbarEvent(event)) {
39
94
  event.preventDefault();
40
- await fetch(`${updatePreviewURL}?token=${event.detail.ref}`);
95
+ await fetch(updatePreviewURL);
41
96
  window.location.reload();
42
97
  }
43
98
  };
44
- const prismicPreviewEnd = async (event) => {
99
+ const handlePrismicPreviewEnd = async (event) => {
45
100
  event.preventDefault();
46
101
  await fetch(exitPreviewURL);
47
102
  window.location.reload();
48
103
  };
49
104
  if (window) {
50
- window.addEventListener("prismicPreviewUpdate", prismicPreviewUpdate);
51
- window.addEventListener("prismicPreviewEnd", prismicPreviewEnd);
105
+ window.addEventListener("prismicPreviewUpdate", handlePrismicPreviewUpdate);
106
+ window.addEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
52
107
  }
53
108
  return () => {
54
109
  if (window) {
55
- window.removeEventListener("prismicPreviewUpdate", prismicPreviewUpdate);
56
- window.removeEventListener("prismicPreviewEnd", prismicPreviewEnd);
110
+ window.removeEventListener("prismicPreviewUpdate", handlePrismicPreviewUpdate);
111
+ window.removeEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
57
112
  }
58
113
  };
59
114
  }, []);
@@ -66,8 +121,8 @@ const isPrismicNextPreviewData = (previewData) => {
66
121
  return typeof previewData === "object" && "ref" in previewData;
67
122
  };
68
123
  const enableAutoPreviews = (config) => {
69
- if ("context" in config && config.context) {
70
- const previewData = config.context.previewData;
124
+ if ("previewData" in config && config.previewData) {
125
+ const { previewData } = config;
71
126
  if (isPrismicNextPreviewData(previewData) && previewData.ref) {
72
127
  config.client.queryContentFromRef(previewData.ref);
73
128
  }
@@ -93,6 +148,7 @@ async function redirectToPreviewURL({
93
148
  previewToken: token
94
149
  });
95
150
  res.redirect(previewUrl);
151
+ return;
96
152
  }
97
153
  res.redirect(defaultURL);
98
154
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismicio/next",
3
- "version": "0.0.1",
3
+ "version": "0.0.5",
4
4
  "description": "Integrate Prismic into a Next.js app",
5
5
  "keywords": [
6
6
  "typescript",
@@ -1,5 +1,9 @@
1
1
  import React, { useEffect } from "react";
2
2
  import { PrismicToolbar } from "@prismicio/react";
3
+ import { useRouter } from "next/router";
4
+
5
+ import { getCookie } from "../lib/getCookie";
6
+ import { extractPreviewRefRepositoryName } from "../lib/extractPreviewRefRepositoryName";
3
7
 
4
8
  /**
5
9
  * Props for `<PrismicPreview>`.
@@ -56,38 +60,66 @@ export function PrismicPreview({
56
60
  updatePreviewURL = "/api/preview",
57
61
  exitPreviewURL = "/api/exit-preview",
58
62
  }: PrismicPreviewProps): JSX.Element {
63
+ const router = useRouter();
64
+
59
65
  useEffect(() => {
60
- const prismicPreviewUpdate = async (event: Event) => {
66
+ const previewRefRepositoryName = extractPreviewRefRepositoryName(
67
+ getCookie("io.prismic.preview", globalThis.document.cookie) as string,
68
+ );
69
+
70
+ const startPreviewIfLoadedFromSharedLink = async () => {
71
+ if (previewRefRepositoryName === repositoryName && !router.isPreview) {
72
+ await fetch(updatePreviewURL);
73
+ window.location.reload();
74
+ }
75
+ };
76
+
77
+ startPreviewIfLoadedFromSharedLink();
78
+
79
+ const handlePrismicPreviewUpdate = async (event: Event) => {
61
80
  if (isPrismicUpdateToolbarEvent(event)) {
62
81
  // Prevent the toolbar from reloading the page.
63
82
  event.preventDefault();
64
- // Update the preview cookie.
65
- await fetch(`${updatePreviewURL}?token=${event.detail.ref}`);
66
83
 
67
- // Reload the page with the updated token.
84
+ // Start Next.js Preview Mode via the given preview API endpoint.
85
+ await fetch(updatePreviewURL);
86
+
87
+ // Reload the page with an active Preview Mode.
68
88
  window.location.reload();
69
89
  }
70
90
  };
71
91
 
72
- const prismicPreviewEnd = async (event: Event) => {
92
+ const handlePrismicPreviewEnd = async (event: Event) => {
93
+ // Prevent the toolbar from reloading the page.
73
94
  event.preventDefault();
95
+
96
+ // Exit Next.js Preview Mode via the given preview API endpoint.
74
97
  await fetch(exitPreviewURL);
98
+
99
+ // Reload the page with an active Preview Mode.
75
100
  window.location.reload();
76
101
  };
77
102
 
103
+ // Register Prismic Toolbar event handlers.
78
104
  if (window) {
79
- window.addEventListener("prismicPreviewUpdate", prismicPreviewUpdate);
80
-
81
- window.addEventListener("prismicPreviewEnd", prismicPreviewEnd);
105
+ window.addEventListener(
106
+ "prismicPreviewUpdate",
107
+ handlePrismicPreviewUpdate,
108
+ );
109
+ window.addEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
82
110
  }
83
111
 
112
+ // On cleanup, unregister Prismic Toolbar event handlers.
84
113
  return () => {
85
114
  if (window) {
86
115
  window.removeEventListener(
87
116
  "prismicPreviewUpdate",
88
- prismicPreviewUpdate,
117
+ handlePrismicPreviewUpdate,
118
+ );
119
+ window.removeEventListener(
120
+ "prismicPreviewEnd",
121
+ handlePrismicPreviewEnd,
89
122
  );
90
- window.removeEventListener("prismicPreviewEnd", prismicPreviewEnd);
91
123
  }
92
124
  };
93
125
  }, []);
@@ -1,6 +1,5 @@
1
1
  import { PreviewData } from "next";
2
2
  import { Client, HttpRequestLike } from "@prismicio/client";
3
- import { NextContextLike } from "./types";
4
3
 
5
4
  interface PrismicNextPreviewData {
6
5
  ref: string;
@@ -40,7 +39,7 @@ export type EnableAutoPreviewsConfig<
40
39
  * Pass a `context` object when using `enableAutoPreviews` outside a
41
40
  * Next.js API endpoint.
42
41
  */
43
- context?: NextContextLike<TPreviewData>;
42
+ previewData?: TPreviewData;
44
43
  }
45
44
  | {
46
45
  /**
@@ -58,16 +57,14 @@ export type EnableAutoPreviewsConfig<
58
57
  *
59
58
  * @param config - Configuration for the function.
60
59
  */
61
- export const enableAutoPreviews = <
62
- TPreviewData extends PreviewData = PreviewData,
63
- >(
60
+ export const enableAutoPreviews = <TPreviewData extends PreviewData>(
64
61
  config: EnableAutoPreviewsConfig<TPreviewData>,
65
62
  ): void => {
66
63
  /**
67
64
  * If preview data is being passed from Next Context then use queryContentFromRef
68
65
  */
69
- if ("context" in config && config.context) {
70
- const previewData = config.context.previewData;
66
+ if ("previewData" in config && config.previewData) {
67
+ const { previewData } = config;
71
68
 
72
69
  if (isPrismicNextPreviewData(previewData) && previewData.ref) {
73
70
  config.client.queryContentFromRef(previewData.ref);
package/src/index.ts CHANGED
@@ -6,8 +6,4 @@ export { exitPreview } from "./exitPreview";
6
6
  export { PrismicPreview } from "./PrismicPreview";
7
7
  export { enableAutoPreviews } from "./enableAutoPreviews";
8
8
  export { redirectToPreviewURL } from "./redirectToPreviewURL";
9
- export type {
10
- NextContextLike,
11
- CreateClientConfig,
12
- PreviewConfig,
13
- } from "./types";
9
+ export type { CreateClientConfig, PreviewConfig } from "./types";
@@ -40,6 +40,8 @@ export async function redirectToPreviewURL({
40
40
  });
41
41
 
42
42
  res.redirect(previewUrl);
43
+
44
+ return;
43
45
  }
44
46
 
45
47
  res.redirect(defaultURL);
@@ -1,4 +1,5 @@
1
1
  import { NextApiResponse, NextApiRequest } from "next";
2
+ import * as prismic from "@prismicio/client";
2
3
 
3
4
  /**
4
5
  * Configuration for `setPreviewData`.
@@ -12,6 +13,7 @@ export type SetPreviewDataConfig = {
12
13
  */
13
14
  req: {
14
15
  query: NextApiRequest["query"];
16
+ cookies: NextApiRequest["cookies"];
15
17
  };
16
18
 
17
19
  /**
@@ -32,8 +34,9 @@ export async function setPreviewData({
32
34
  req,
33
35
  res,
34
36
  }: SetPreviewDataConfig): Promise<void> {
35
- if (req.query.token) {
36
- const { token: ref } = req.query;
37
+ const ref = req.query.token || req.cookies[prismic.cookie.preview];
38
+
39
+ if (ref) {
37
40
  res.setPreviewData({ ref });
38
41
  }
39
42
  }
package/src/types.ts CHANGED
@@ -2,26 +2,18 @@ import { PreviewData, NextApiRequest, NextApiResponse } from "next";
2
2
  import { LinkResolverFunction } from "@prismicio/helpers";
3
3
  import { Client } from "@prismicio/client";
4
4
 
5
- /**
6
- * Next.js context object from APIs supporting Preview Mode. This includes the
7
- * context object from `getStaticProps` and `getServerSideProps`.
8
- */
9
- export type NextContextLike<TPreviewData extends PreviewData = PreviewData> = {
10
- previewData?: TPreviewData;
11
- };
12
-
13
5
  /**
14
6
  * Configuration for creating a Prismic client with automatic preview support in
15
7
  * Next.js apps.
16
8
  */
17
9
  export type CreateClientConfig = {
18
10
  /**
19
- * A Next.js context object (such as the context object from `getStaticProps`
20
- * or `getServerSideProps`).
11
+ * Preview data coming from Next.js context object. This context object comes
12
+ * from `getStaticProps` or `getServerSideProps`.
21
13
  *
22
- * Pass a `context` when using outside a Next.js API endpoint.
14
+ * Pass `previewData` when using outside a Next.js API endpoint.
23
15
  */
24
- context?: NextContextLike;
16
+ previewData?: PreviewData;
25
17
 
26
18
  /**
27
19
  * A Next.js API endpoint request object.