Cannot import react in mdx files
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
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.