nextra icon indicating copy to clipboard operation
nextra copied to clipboard

Cannot import react in mdx files

Open karlbaumg opened this issue 11 months ago • 1 comments

Describe the bug A clear and concise description of what the bug is.

I'm migrating from v3 to v4 and I got everything working under a subpath /docs of my site but it's just that the react functions like createContext cannot be imported. Here is the build log:

- error [nextra] Error while loading { pathSegments: [] } TypeError: (0 , d.createContext) is not a function
    at 38050 (.next/server/app/docs/[[...mdxPath]]/page.js:25:54381)
    at t (.next/server/webpack-runtime.js:1:127)
    at i (.next/server/app/docs/[[...mdxPath]]/page.js:1:477)
    at o (.next/server/app/docs/[[...mdxPath]]/page.js:5:77809)
    at async h (.next/server/app/docs/[[...mdxPath]]/page.js:5:78295)

To Reproduce Steps to reproduce the behavior:

My folder structure is as follows:

app
├── (default)
│   ├── about
│   │   └── page.tsx
│   ├── cookie-policy
│   │   └── page.tsx
│   ├── layout.tsx
│   ├── page.tsx
│   ├── pricing
│   │   ├── layout.tsx
│   │   └── page.tsx
│   ├── privacy-policy
│   │   └── page.tsx
│   └── terms-of-service
│       └── page.tsx
├── docs
│   ├── layout.tsx
│   └── [[...mdxPath]]
│       └── page.tsx
├── layout.tsx
├── _meta.tsx
content
├── subtitle1
│   ├── a.mdx
│   ├── b.mdx
│   └── _meta.tsx
├── index.mdx
├── _meta.tsx
└── subtitle2
    ├── a.mdx
    ├── b.mdx
    ├── _meta.tsx

Here is my next.config.mjs:

import nextra from "nextra";
// import { NextConfig } from "next";

const nextConfig = {
  output: "export",
  reactStrictMode: true,
  productionBrowserSourceMaps: true,
  images: {
    unoptimized: true,
  },
};

const withNextra = nextra({
  contentDirBasePath: "/docs",
  defaultShowCopyCode: true,
});

export default withNextra(nextConfig);

I've deleted my existing nextra.config.tsx as it is not used in v4 as far as I understood.

Here is how I import createContext from react in content/index.mdx:

import { Tabs, Steps } from 'nextra/components'
import Image from 'next/image'
import {createContext, useContext, useState} from 'react'

export const getInitialOSIndex = () => {
  if (typeof window === "undefined") return 0;
  console.log({ userAgent: window.navigator.userAgent });
  const { userAgent } = window.navigator;
  const macos = /(macintosh|macintel|macppc|mac68k|macos)/i.test(userAgent.toLowerCase());
  const windows = /(win32|win64|windows|wince)/i.test(userAgent.toLowerCase());
  const linux = /linux/i.test(userAgent.toLowerCase());
  return macos ? 0 : windows ? 1 : linux ? 2 : 0;
}

export const TabContext = createContext({
  selectedIndex: getInitialOSIndex(),
  setSelectedIndex: () => {},
})

export const TabProvider = ({ children }) => {
  const [selectedIndex, setSelectedIndex] = useState(getInitialOSIndex())
  return (
    <TabContext.Provider value={{ selectedIndex, setSelectedIndex }}>
      {children}
    </TabContext.Provider>
  )
}

export const SyncedTabs = ({ items, children }) => {
  const { selectedIndex, setSelectedIndex } = useContext(TabContext)
  return (
    <Tabs items={items} selectedIndex={selectedIndex} onChange={setSelectedIndex}>
      {children}
    </Tabs>
  )
}

....

Expected behavior

Just continue working as it was working in v3.

Desktop (please complete the following information):

  • OS: Ubuntu 24.04
  • Browser: Zen Browser (Firefox)
  • Version 24.04

Additional context

  • NextJS 15
  • React 19
  • TailwindCSS 4
  • Nextra 4.1.1

karlbaumg avatar Jan 28 '25 23:01 karlbaumg

Moving the components to a .tsx file with use client directive and importing that file in .mdx solved the issue. Keeping the issue open in case the expected behavior is to be able to have client-side components in .mdx files directly.

karlbaumg avatar Jan 29 '25 09:01 karlbaumg