Skip to content

Commit

Permalink
refactor: replace preview mode with draft mode
Browse files Browse the repository at this point in the history
  • Loading branch information
alexgoff committed Sep 19, 2024
1 parent fd05b6a commit b77bd49
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 53 deletions.
2 changes: 1 addition & 1 deletion .env.local.sample
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ NEXT_PUBLIC_BASE_URL=http://localhost:3000
NEXT_PUBLIC_CONTACT_FORM_POST_URL=http://localhost:8080/actions/contact-form/send
NEXT_PUBLIC_GOOGLE_APP_ID=
CRAFT_REVALIDATE_SECRET_TOKEN=
CRAFT_SECRET_TOKEN=
CLOUD_ENV = DEV
NEXT_PREVIEW_SLUG=
NEXT_PUBLIC_DEBUG_LOGGING=
NEXT_PUBLIC_RELEASE_URL=
NEXT_PUBLIC_EFD_URL=
Expand Down
12 changes: 4 additions & 8 deletions pages/[locale]/[[...uriSegments]].js
Original file line number Diff line number Diff line change
Expand Up @@ -107,23 +107,19 @@ export async function getStaticPaths() {
export async function getStaticProps({
params: { uriSegments, locale },
previewData,
draftMode,
}) {
const PREVIEW_SLUG = process.env.NEXT_PREVIEW_SLUG;

if (process.env.NEXT_DEBUG_LOGGING === "true") {
logNextDir();
}

const runId = Date.now().toString();
const isPreview = previewData && uriSegments[0] === PREVIEW_SLUG;
const isEspanol = locale === "es";
const site = getSiteFromLocale(locale);
let uri = CRAFT_HOMEPAGE_URI;
let previewToken;
if (isPreview) {
uri = previewData.uriSegments.join("/");
previewToken = previewData?.previewToken;
} else if (uriSegments && uriSegments.length) {
const previewToken = draftMode ? previewData?.previewToken : undefined;

if (uriSegments && uriSegments.length) {
uri = uriSegments.join("/");
}

Expand Down
99 changes: 55 additions & 44 deletions pages/api/preview.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,60 @@
import { isCraftPreview } from "@/helpers";
import { getEntryDataByUid } from "@/api/entry";

const preview = async (req, res) => {
const PREVIEW_SLUG = process.env.NEXT_PREVIEW_SLUG;
const { query } = req;
const isPreview = isCraftPreview(query);
// N.B. previewToken isn't consistently available
const previewToken = query.token || undefined;
if (!query.entryUid)
return res
.status(401)
.json({ message: "Not allowed to access this route" });

if (!isPreview)
return res.status(401).json({
message: `Preview Mode must be enabled to view entry "${query.entryUid}"`,
});

// Fetch the headless CMS to check if the provided entry exists
const site = query.site === "ES" ? "es" : "default";
const entry = await getEntryDataByUid(query.entryUid, site, previewToken);
if (!entry?.uri)
return res.status(401).json({
message: `URI of the entry "${query.entryUid}" could not be fetched`,
});

// const { pathname } = new URL(entry.url.replace("/es/es", "/es"));
const { uri } = entry;
// N.B. Because previewToken presence is unreliable, we're always redirecting to previewUri so real pages are never inadvertently updated.
// If a previewToken becomes reliable, inclusion of previewToken in the preview data should be enough (and could use real page uri as redirect)
const previewUri = `/${PREVIEW_SLUG}`;

// Enable Preview Mode by setting the cookies
res.setPreviewData(
{
previewToken,
uriSegments: uri.split("/"),
},
{
maxAge: 120,
path: previewUri,
import { gql } from "graphql-request";
import { queryAPI } from "@/lib/fetch";
import { getLocaleString, getSiteFromLocale } from "@/lib/utils";

const PREVIEW_SECRET_TOKEN = process.env.CRAFT_SECRET_TOKEN;
const CRAFT_HOMEPAGE_URI = "__home__";

const Query = gql`
query PagePreviewQuery($site: [String], $uri: [String]) {
entry(site: $site, uri: $uri) {
uri
title
}
}
`;

/**
* @function preview
* @param {import("next").NextApiRequest} request
* @param {import("next").NextApiResponse} response
*/
const preview = async (request, response) => {
const searchParams = new URLSearchParams(request.query);

const secret = searchParams.get("secret");
const previewToken = searchParams.get("token");
const site = getSiteFromLocale(
(searchParams.get("site") || "en").toLowerCase()
);
// Redirect to the path from the fetched url
res.redirect(previewUri);
const locale = getLocaleString(site);
const uri = searchParams.get("uri");

// Check the secret and next parameters
// This secret should only be known to this route handler and the CMS
if (secret !== PREVIEW_SECRET_TOKEN) {
return response.status(401).send({ message: "Invalid token" });
}

if (!uri) {
return response.status(401).send({ message: "URI missing" });
}

const res = await queryAPI(Query, undefined, previewToken, { site, uri });

// If the uri doesn't exist prevent draft mode from being enabled
if (!res?.entry?.uri) {
return response.status(401).send({ message: "Invalid uri" });
}

const redirectUri = res.entry.uri === CRAFT_HOMEPAGE_URI ? "" : res.entry.uri;
const redirect = `/${locale}/${redirectUri}`;
const cookiePath = `${site === "default" ? "" : `/${locale}`}/${redirectUri}`;

// Enable Draft Mode by setting the cookie
response.setDraftMode({ enable: true });
response.setPreviewData({ previewToken }, { path: cookiePath, maxAge: 120 });
response.redirect(redirect);
};

export default preview;

0 comments on commit b77bd49

Please sign in to comment.