← all conversations

Next.js prerendering error

2025-06-215 turns8,361 charsgpt-4o, o4-mini1 fork(s)
nextjsprerenderingbuild-error

Summary

User encountered a Next.js prerendering error during the build process.

Messages

⑂ thread forked here
rm -rf .next node_modules && npm install && npm run build added 539 packages, and audited 540 packages in 4s 274 packages are looking for funding run `npm fund` for details found 0 vulnerabilities > next-animated-portfolio@0.1.0 build > next build ✓ Linting and checking validity of types ✓ Collecting page data Error occurred prerendering page "/blog/2024-12-19-H omeless-Guide-Austin". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: Cannot read properties of null (reading ' useState') at exports.useState (/Users/danielkliewer/page06 /node_modules/react/cjs/react.production.js:530:33) at MDXRemote (file:///Users/danielkliewer/page06 /node_modules/next-mdx-remote/dist/index.js:13:51) at nF (/Users/danielkliewer/page06/node_modules/ next/dist/compiled/next-server/app-page.runtime.prod.js:76:46843) at nH (/Users/danielkliewer/page06/node_modules/ next/dist/compiled/next-server/app-page.runtime.prod.js:76:48618) at nW (/Users/danielkliewer/page06/node_modules/ next/dist/compiled/next-server/app-page.runtime.prod.js:76:67762) at nz (/Users/danielkliewer/page06/node_modules/ next/dist/compiled/next-server/app-page.runtime.prod.js:76:65337) at nY (/Users/danielkliewer/page06/node_modules/ next/dist/compiled/next-server/app-page.runtime.prod.js:76:71193) at nH (/Users/danielkliewer/page06/node_modules/ next/dist/compiled/next-server/app-page.runtime.prod.js:76:60968) at nW (/Users/danielkliewer/page06/node_modules/ next/dist/compiled/next-server/app-page.runtime.prod.js:76:67762) at nz (/Users/danielkliewer/page06/node_modules/ next/dist/compiled/next-server/app-page.runtime.prod.js:76:65337) Export encountered an error on /blog/[slug]/page: /b log/2024-12-19-Homeless-Guide-Austin, exiting the build. ⨯ Next.js build worker exited with code: 1 and sign al: null
The error you're encountering during the `next build` process: ``` TypeError: Cannot read properties of null (reading 'useState') ``` suggests that **React hooks like `useState` are being called in a context where they're not allowed**, likely during static prerendering of an MDX file via `next-mdx-remote`. ### 🔍 Breakdown of the problem: The file `/blog/2024-12-19-Homeless-Guide-Austin` is likely using something like: ```tsx import { useState } from 'react'; const SomeComponent = () => { const [state, setState] = useState(false); ... }; ``` If this is part of an **MDX file being rendered during `getStaticProps` or `getStaticPaths`**, then: - **You cannot use React hooks** directly in MDX unless it's being rendered **at runtime inside a React component**, **not during static prerendering**. --- ### ✅ Solutions: #### Option 1: Ensure MDX is only hydrated on the client If you're using `next-mdx-remote`, make sure you're rendering the MDX properly. For example: ```tsx import { MDXRemote } from 'next-mdx-remote'; import { MDXRemoteSerializeResult } from 'next-mdx-remote'; import dynamic from 'next/dynamic'; const components = { // dynamically import components that use hooks InteractiveComponent: dynamic(() => import('@/components/InteractiveComponent'), { ssr: false }), }; export default function PostPage({ source }: { source: MDXRemoteSerializeResult }) { return <MDXRemote {...source} components={components} />; } ``` This prevents `useState` from being called during server-side rendering. --- #### Option 2: SSR-safe fallback You can wrap the hook-using components like so: ```tsx 'use client'; import { useState } from 'react'; export default function MyClientOnlyComponent() { const [open, setOpen] = useState(false); return <button onClick={() => setOpen(!open)}>{open ? "Open" : "Closed"}</button>; } ``` Then ensure that the MDX component rendering this is not SSR’d, or is only rendered conditionally on the client. --- #### Option 3: Check if you're accidentally invoking hooks in `getStaticProps` Don’t ever do: ```ts const { useState } = require('react'); const something = useState(false); // ❌ ``` During your `getStaticProps` or `getStaticPaths`. --- ### 🧼 How to Debug Fast 1. **Open `/blog/2024-12-19-Homeless-Guide-Austin.mdx`** 2. Search for any components that might be using `useState`, `useEffect`, etc. 3. Either: - Wrap them in `dynamic(..., { ssr: false })`, or - Remove them from static MDX and replace with client-only hydration --- If you're unsure which component is causing the error, try temporarily commenting out chunks of the MDX file until the build succeeds. Once you've isolated the culprit, refactor that component. Want to paste the content of the `2024-12-19-Homeless-Guide-Austin.mdx` post here? I can point out the exact line or component that needs to be moved or rewritten.
gpt-4o
⚙ model reasoning step
o4-mini
⚙ model reasoning step
o4-mini
The stack‐trace here… ``` TypeError: Cannot read properties of null (reading 'useState') at exports.useState (…/react.production.js:530:33) at MDXRemote (…/next-mdx-remote/dist/index.js:13:51) … ``` …is a dead‐giveaway that you’re trying to render a component that calls React hooks (here, MDXRemote internally calls `useState`) *in a Server Component*. In Next 13’s App Router, all files under `app/` are **Server Components** by default, and you can’t call hooks there—hence `useState` is actually `null`. --- ## Two easy fixes 1. **Wrap your MDX renderer in a Client Component** - Create a small wrapper under, say, `components/MDXClient.tsx`: ```tsx "use client"; import { MDXRemote, MDXRemoteSerializeResult } from "next-mdx-remote"; interface MDXClientProps { source: MDXRemoteSerializeResult; components?: Record<string, React.ComponentType>; } export default function MDXClient({ source, components }: MDXClientProps) { return <MDXRemote {...source} components={components} />; } ``` - In your page (still a Server Component), import and use it: ```tsx // app/blog/[slug]/page.tsx import { getMdxSource } from "@/lib/mdx"; // however you load/serialize import MDXClient from "@/components/MDXClient"; export default async function BlogPage({ params: { slug } }) { const mdxSource = await getMdxSource(slug); return ( <article> <h1>{mdxSource.frontmatter.title}</h1> <MDXClient source={mdxSource} /> </article> ); } ``` This way, the hook‐using MDXRemote lives inside a file that begins with `"use client"`, and your page stays a Server Component. 2. **Use dynamic import with SSR disabled** If you’d rather not create a dedicated client‐only file, you can import MDXRemote dynamically: ```tsx // app/blog/[slug]/page.tsx import dynamic from "next/dynamic"; import { getMdxSource } from "@/lib/mdx"; const MDXRemote = dynamic( () => import("next-mdx-remote").then(mod => mod.MDXRemote), { ssr: false } ); export default async function BlogPage({ params: { slug } }) { const mdxSource = await getMdxSource(slug); return ( <article> <h1>{mdxSource.frontmatter.title}</h1> <MDXRemote {...mdxSource} /> </article> ); } ``` This tells Next to only load and render `MDXRemote` on the client side, avoiding hooks on the server. --- ### Why it happens - **Server Components** (the default under `app/`) **cannot** call hooks like `useState`, `useEffect`, etc. - `MDXRemote` internally uses `useState` to walk and render your MDX tree. - Attempting to invoke it in a Server Component gives you exactly this “reading ‘useState’ of null” error. Next.js docs on the App Router and client vs. server components have more on this: <https://nextjs.org/docs/getting-started/react-essentials#servers-and-clients> --- Once you move all hook‐invoking logic into a client boundary (either via `"use client"` or `dynamic(..., { ssr: false })`), `next build` will finish your prerender step without error.
o4-mini