Created
March 6, 2024 09:47
-
-
Save manuel-schoebel/e32b430336a02621cb92bf60ade2663e to your computer and use it in GitHub Desktop.
Next.js revalidation for headless cms
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // route handler enabling draft mode | |
| import { getPageByPath } from "@/lib/api/getPageByPath"; | |
| import { defaultLocale } from "@/config/i18n"; | |
| import { draftMode } from "next/headers"; | |
| import { redirect } from "next/navigation"; | |
| export async function GET(request: Request) { | |
| const { searchParams } = new URL(request.url); | |
| const secret = searchParams.get("secret"); | |
| const path = searchParams.get("path"); | |
| const locale = searchParams.get("locale"); | |
| const disable = searchParams.get("disable"); | |
| // Check the secret and next parameters | |
| // This secret should only be known to this route handler and the CMS | |
| console.log("secret", secret, process.env.FRONTEND_API_TOKEN); | |
| if (secret !== process.env.FRONTEND_API_TOKEN) { | |
| return new Response("Invalid token", { status: 401 }); | |
| } | |
| if (disable) { | |
| draftMode().disable(); | |
| // response with disabled success message | |
| return new Response("disabled", { status: 200 }); | |
| } | |
| if (!path) { | |
| return new Response("No path given", { status: 401 }); | |
| } | |
| const page = await getPageByPath(path, locale || defaultLocale, true); | |
| if (!page?.attributes?.path) { | |
| return new Response("invalid path", { status: 401 }); | |
| } | |
| draftMode().enable(); | |
| redirect(page.attributes?.path); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { GetPageDocument, PublicationState } from "@/graphql/generated/graphql"; | |
| import { getClient } from "@/lib/graphqlRequestClient"; | |
| import { draftMode } from "next/headers"; | |
| import { cache as reactCache } from "react"; | |
| export const getPageByPath = reactCache( | |
| async (path: string, locale: string, isDraft?: boolean) => { | |
| // using next helper methods you can see if draft mode is enabled | |
| // essentially it is just a cookie set by the draftmode api call | |
| const { isEnabled } = draftMode(); | |
| const client = getClient(); | |
| const filters = { | |
| path: { | |
| eq: path, | |
| }, | |
| }; | |
| const response = await client.request(GetPageDocument, { | |
| locale, | |
| filters, | |
| limit: 1, | |
| offset: 0, | |
| publicationState: | |
| isDraft || isEnabled ? PublicationState.Preview : PublicationState.Live, | |
| }); | |
| if (!response?.pages?.data || response?.pages?.data.length === 0) { | |
| return; | |
| } | |
| const [page] = response?.pages?.data; | |
| return page; | |
| } | |
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // route handler enabling draft mode | |
| import { getPageByPath } from "@/lib/api/getPageByPath"; | |
| import { defaultLocale } from "@/config/i18n"; | |
| import { revalidatePath } from "next/cache"; | |
| import { NextResponse } from "next/server"; | |
| export async function POST(request: Request) { | |
| const { secret, path, locale } = await request.json(); | |
| // Check the secret and next parameters | |
| // This secret should only be known to this route handler and the CMS | |
| if (secret !== process.env.FRONTEND_API_TOKEN) { | |
| return new Response("Invalid token", { status: 401 }); | |
| } | |
| if (!path) { | |
| return new Response("Invalid path", { status: 401 }); | |
| } | |
| const page = await getPageByPath(path, locale || defaultLocale); | |
| if (!page?.attributes?.path) { | |
| return new Response("invalid path", { status: 401 }); | |
| } | |
| const revalidationPath = `/${locale}${path}`; | |
| try { | |
| revalidatePath(revalidationPath); | |
| } catch (e) { | |
| console.error("error revalidating", e); | |
| throw e; | |
| } | |
| return NextResponse.json({ revalidate: true }); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment