Encountering 'undefined prototype' issue with react-notion-x in Next.js

I’m currently developing a Next.js application and attempting to render Notion content using the react-notion-x library. However, I constantly face this frustrating error message: “Cannot read properties of undefined (reading ‘prototype’)”. This issue arises whenever I attempt to import the library.

Steps I’ve taken:

  1. Added react-notion-x to my Next.js app
  2. Implemented the NotionRenderer component to display information from Notion
  3. Launched the project and encountered the same error

Expected outcome:
The NotionRenderer should present the Notion content flawlessly.

What actually happens:
This is the error I receive:

Unhandled Runtime Error
Error: Cannot read properties of undefined (reading 'prototype')

Test page ID I am using:
Reference from the documentation: 067dd719a912471ea9a3ac10710e7fdf

Troubleshooting steps taken:
I attempted removing and reinstalling the react-notion-x library and upgrading it to the latest version. I also ensured I was passing all necessary props to NotionRenderer and verified that the data structure was correctly formatted, but nothing seemed to resolve the issue.

Here’s the code I’ve been using:

import Container from "@/components/elements/Container"
import PageHeading from "@/components/elements/PageHeading"
import BackButton from "@/components/elements/BackButton"
import { NotionRenderer } from "react-notion-x"
import { NotionAPI } from 'notion-client'

const notion = new NotionAPI()

export default async function ProjectDetailPage({ params }) {
  
  const recordMap = await notion.getPage('067dd719a912471ea9a3ac10710e7fdf')
  console.log(recordMap)
  
  return (
    <>
      <Container>
        <BackButton />
        <PageHeading title="" />
        <NotionRenderer recordMap={recordMap} fullPage={true} darkMode={false} />
      </Container>
    </>
  )
}

Dependencies I’m using:

{
  "dependencies": {
    "@emotion/react": "^11.11.1",
    "@emotion/styled": "^11.11.0",
    "@jridgewell/sourcemap-codec": "^1.4.15",
    "@notionhq/client": "^2.2.13",
    "@radix-ui/react-dialog": "^1.0.5",
    "@radix-ui/react-popover": "^1.0.7",
    "@radix-ui/react-slot": "^1.0.2",
    "@radix-ui/react-tooltip": "^1.0.7",
    "aos": "^2.3.4",
    "class-variance-authority": "^0.7.0",
    "clsx": "^2.0.0",
    "cmdk": "^0.2.0",
    "framer-motion": "^10.16.4",
    "lucide-react": "^0.279.0",
    "next": "^13.5.4",
    "next-themes": "^0.2.1",
    "nextjs-toploader": "^1.4.2",
    "node-fetch": "^3.3.2",
    "notion-client": "^6.16.0",
    "react": "latest",
    "react-dom": "latest",
    "react-icons": "^4.11.0",
    "react-notion-x": "^6.15.6",
    "tailwind-merge": "^1.14.0",
    "tailwindcss-animate": "^1.0.7",
    "usehooks-ts": "^2.9.1",
    "zustand": "^4.4.1"
  }
}

This is a Next.js 13+ hydration mismatch issue. react-notion-x expects certain DOM elements during rendering, but they’re not there initially with SSR. I hit the same problem and found dynamic imports with ssr: false work better than client wrappers. Try this: const NotionRenderer = dynamic(() => import('react-notion-x').then(mod => ({ default: mod.NotionRenderer })), { ssr: false }) at the top of your component. Don’t forget to import dynamic from next/dynamic. This stops the component from rendering server-side, which kills those prototype errors since the problematic code only runs in the browser where those properties exist.

Had this exact issue when I moved to Next.js 13+ with app router. The problem is react-notion-x has client-side code that breaks with server-side rendering in the new app directory. Since you’re using an async component, you’re probably in app router which defaults to server components. Easiest fix: create a client component wrapper. Make a NotionWrapper.jsx file, stick 'use client' at the top, then import and use NotionRenderer there. Import this wrapper in your server component instead. This keeps the client-side code separate from the server stuff. Or you could just move your page back to the pages directory if you’re not married to app router yet. I went with the wrapper approach and it killed those prototype errors instantly without touching any dependencies.