I am trying to use NextJS app directory with Contentful live-preview, and I keep getting this error:
Error: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function
Which is coming from:
(rsc)/./node_modules/.pnpm/@[email protected][email protected][email protected][email protected][email protected]/node_modules/@contentful/live-preview/dist/react.js
My preview in Contentful is linked to my home page content type, and the URL is:
http://localhost:3000/api/preview/home?secret={*removed secret*}&slug={entry.fields.slug
Here is what I have:
// app/layout.tsx
import { ContentfulLivePreviewProvider } from '@contentful/live-preview/react'
import { ReactNode } from "react"
import Footer from 'components/layout/Footer'
import Header from 'components/layout/Header'
import "./globals.css"
export default function RootLayout({
children,
}: {
children: ReactNode
}) {
return (
<html lang="en">
<body>
<div>
<ContentfulLivePreviewProvider locale="en-US">
<Header/>
<main>
{children}
</main>
<Footer />
</ContentfulLivePreviewProvider>
</div>
</body>
</html>
)
}
// app/page.tsx
import { draftMode } from "next/headers";
import { getHomePage } from "lib/contentful/api"
export default async function HomePage({ searchParams }: {
searchParams: {
[key: string]: string | string[] | undefined
}
}) {
const { isEnabled } = draftMode();
const homepage = await getHomePage(isEnabled);
const { heading } = homepage.data.homePage
return (
<h1>{heading}</h1>
)
}
// app/api/preview/home/route.ts
import { draftMode } from 'next/headers';
import { getHomePage } from 'lib/contentful/api';
import { redirect } from 'next/navigation'
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const secret = searchParams.get('secret')
if (!secret) {
return new Response('Missing parameters', { status: 400 })
}
if (secret !== process.env.CONTENTFUL_PREVIEW_SECRET) {
return new Response('Invalid token', { status: 401 })
}
const homePage = await getHomePage(true)
if (!homePage) {
return new Response('Home page content was not recieved', { status: 401 })
}
draftMode().enable()
redirect('/')
}
// lib/contentful/api.ts
async function fetchGraphQL(query: string, preview = false): Promise<any> {
return fetch(
`https://graphql.contentful.com/content/v1/spaces/${process.env.CONTENTFUL_SPACE_ID}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${
preview
? process.env.CONTENTFUL_PREVIEW_ACCESS_TOKEN
: process.env.CONTENTFUL_ACCESS_TOKEN
}`,
},
body: JSON.stringify({ query }),
next: { tags: ["posts"] },
},
).then((response) => response.json());
}
export async function getHomePage(isDraftMode = false) {
const homePage = await fetchGraphQL(
`query {
homePage(id: "WCCFbXWLV6FaesGZY6wgA") {
__typename
sys {
id
}
heading
}
}`,
isDraftMode
)
return homePage
}
Normally that kind of an error comes into play when you are needing use client
but this is something that needs to be in layout. This error only appears once I add the ContentfulLivePreview provider to my layout.
All the examples I could find show it being used with pages/_app
, but I really don’t want to do that.