@prismicio/next
Version:
Helpers to integrate Prismic into Next.js apps
72 lines (71 loc) • 2.76 kB
JavaScript
import { cookie, getToolbarSrc } from "@prismicio/client";
import Script from "next/script.js";
import { useEffect } from "react";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { useRouter } from "next/router.js";
//#region src/pages/PrismicPreview.tsx
/**
* React component that sets up Prismic Previews using the Prismic Toolbar. When the Prismic Toolbar
* send events to the browser, such as on preview updates and exiting, this component will
* automatically refresh the page with the changes.
*
* This component can be wrapped around your app or added anywhere in your app's tree. It must be
* rendered on every page.
*/
const PrismicPreview = (props) => {
const { repositoryName, updatePreviewURL = "/api/preview", exitPreviewURL = "/api/exit-preview", children } = props;
const router = useRouter();
const toolbarSrc = getToolbarSrc(repositoryName);
useEffect(() => {
const controller = new AbortController();
window.addEventListener("prismicPreviewUpdate", onUpdate, { signal: controller.signal });
window.addEventListener("prismicPreviewEnd", onEnd, { signal: controller.signal });
if (window.location.href.startsWith(window.location.origin + router.basePath) && getPreviewCookieRepositoryName() === repositoryName && !router.isPreview) start();
function onEnd(event) {
event.preventDefault();
fetch(router.basePath + exitPreviewURL, { signal: controller.signal }).then((res) => {
if (!res.ok) {
console.error(`[<PrismicPreview>] Failed to exit Preview Mode using the "${exitPreviewURL}" API endpoint. Does it exist?`);
return;
}
refresh();
}).catch(() => {});
}
function onUpdate(event) {
event.preventDefault();
start();
}
function start() {
fetch(router.basePath + updatePreviewURL, {
redirect: "manual",
signal: controller.signal
}).then((res) => {
if (res.type !== "opaqueredirect") {
console.error(`[<PrismicPreview>] Failed to start or update the preview using "${updatePreviewURL}". Does it exist?`);
return;
}
refresh();
}).catch(() => {});
}
function refresh() {
router.replace(router.asPath, void 0, { scroll: false });
}
return () => controller.abort();
}, [
exitPreviewURL,
updatePreviewURL,
repositoryName,
router
]);
return /* @__PURE__ */ jsxs(Fragment, { children: [children, /* @__PURE__ */ jsx(Script, {
src: toolbarSrc,
strategy: "lazyOnload"
})] });
};
function getPreviewCookieRepositoryName() {
const cookie$1 = window.document.cookie.split("; ").find((row) => row.startsWith(`${cookie.preview}=`))?.split("=")[1];
return (decodeURIComponent(cookie$1 ?? "").match(/"([^"]+)\.prismic\.io"/) || [])[1];
}
//#endregion
export { PrismicPreview };
//# sourceMappingURL=PrismicPreview.js.map