Next.js

Super expression must either be null or a function: Next.js

Reproduced on Next.js 16.4.0 and 13.5.11: why the carousel import crashes the App Router, the two-file fix that keeps your page a Server Component, and the error that comes next.

Mahdi Ben RhoumaMahdi Ben Rhouma
7 min read

TL;DR#

In the App Router, pages and layouts are Server Components, and in that environment React does not export Component. react-responsive-carousel and its dependency react-easy-swipe define their components as classes that extend React.Component, so the class helper receives undefined the moment the package is imported, and throws. The fix is to import the carousel from a file that starts with 'use client', either your whole component or a two-line wrapper, and keep the page itself a Server Component.

This is what next dev prints when a page imports the carousel directly (Next.js 16.4.0, reproduced on 10 October 2026):

text
⨯ TypeError: Super expression must either be null or a function, not undefined
    at module evaluation (app/page.js:1:1)
    at module evaluation (.next/dev/server/chunks/ssr/[root-of-the-server]__13m0l6c4zkkzd._.js:51:47)
> 1 | import { Carousel } from 'react-responsive-carousel'
    | ^

The browser gets a 500. next build fails on the same import while it collects page data:

text
Error: Failed to collect configuration for /
    at ignore-listed frames {
  [cause]: TypeError: Super expression must either be null or a function, not undefined
      at ignore-listed frames
}
 
> Build error occurred
Error: Failed to collect page data for /

The Stack Overflow question behind this page hit it on Next.js 13 with exactly that import. The same page built on Next.js 13.5.11 (React 18.2.0) fails the same way, with the same message.

Why it happens#

Two facts meet in that one import line.

First, React has a reduced server build. React's package.json maps the react-server export condition to a separate entry point, and that entry, ReactServer.js in the React repository, exports createElement, forwardRef, memo, use, a few hooks such as useId and useMemo, and little else. There is no Component, no PureComponent, no createContext, no useState. The Next.js installation docs note that the App Router uses React canary releases built in, so the copy that matters is the one inside the next package, and its server build has the same gap. Counting the exports in the copy shipped with Next.js 16.4.0 shows it, first for Component, then for PureComponent:

text
node_modules/next/dist/compiled/react/cjs/react.react-server.production.js
0
0
node_modules/next/dist/compiled/react/cjs/react.production.js
1
1

Second, the carousel is a class component. react-responsive-carousel 3.2.23 is the latest release on npm, published in March 2022, and its compiled lib/js folder contains no 'use client' directive. Its Carousel and Thumbs classes extend React.Component, and so does its dependency react-easy-swipe 0.0.21. That dependency is loaded first, and its transpiled _inherits helper is the one that throws:

text
Super expression must either be null or a function, not " + typeof superClass
326:  }(_react.Component);

On the server, _react.Component is undefined, typeof undefined is "undefined", and you get the exact string in your terminal. The stack trace in react-responsive-carousel issue #738, opened against Next.js 13, points at that same react-swipe.js file. Its reporter closed it in November 2023 with no linked commit, and no release has followed, which is why the error still appears on current versions.

Nothing flags it at compile time: in the reproduction, the build reports "Compiled successfully" and only fails when the page module is evaluated to collect page data, because the package reads React.Component as a property while it loads. The Next.js docs on third-party components describe the situation with a carousel as the example: "However, if you try to use it directly within a Server Component, you'll see an error. This is because Next.js doesn't know <Carousel /> is using client-only features."

Fix#

Pick one of the two. Both were built successfully on Next.js 16.4.0, and the wrapper also on 13.5.11.

  1. Keep the page a Server Component and wrap the package. Create a file whose only job is to move the import across the client boundary:
jsx
// app/carousel.js
'use client'
 
import { Carousel } from 'react-responsive-carousel'
 
export default Carousel

Then import the wrapper instead of the package in the page:

jsx
// app/page.js
import Carousel from './carousel'
 
export default function Page() {
  return (
    <Carousel autoPlay infiniteLoop showStatus={false} showThumbs={false} interval={5000}>
      <div>Slide 1</div>
      <div>Slide 2</div>
    </Carousel>
  )
}

This is the pattern the Next.js docs give for third-party components, down to the file name; they show the same file as app/carousel.tsx for TypeScript. The 'use client' reference explains why one file is enough: "You only need to add it to the files whose components you want to render directly within Server Components."

  1. Or mark the component that uses the carousel as a Client Component. Put 'use client' on the first line, before the imports, as in the top-voted answer on Stack Overflow:
jsx
// app/page.js
'use client'
 
import { Carousel } from 'react-responsive-carousel'
 
export default function Page() {
  return (
    <Carousel autoPlay infiniteLoop showStatus={false} showThumbs={false} interval={5000}>
      <div>Slide 1</div>
      <div>Slide 2</div>
    </Carousel>
  )
}

This works, but everything that file imports now ships to the browser, and the page loses what the docs list as Server Component jobs, such as fetching data close to the source or using secrets without exposing them to the client. Use it on a small banner component, not on a whole page.

Verify the fix#

Delete .next and run next build again. With either fix the build gets past "Collecting page data" and prerenders the route:

text
Route (app)
┌ ○ /
└ ○ /_not-found
 
 
○  (Static)  prerendered as static content

Then start next dev again and reload the page; the ⨯ TypeError block should be gone from the terminal.

One email a month — the latest explained errors

What the site published that month — mostly Next.js, Supabase and Node errors, explained. You confirm by email; unsubscribe any time in one click.

"use client" does not mean "no server HTML"#

A reply on issue #738 objects that the carousel should stay server-rendered for SEO, and the third answer on Stack Overflow says the wrapper leaves "only Carousel" in CSR. Both read 'use client' as "browser only", which it is not. The server and client boundary guide says it in a table: a Client Component runs on the server and in the browser; a Server Component runs only on the server. With the wrapper, the prerendered index.html contains the carousel's own markup, outside any script tag:

text
HTML without <script> tags, Carousel markup found: ["<div class=\"carousel-root\">","<div class=\"slider-wrapper axis-horizontal\">"]

So the wrapper keeps the HTML; what changes is that the carousel's JavaScript is also sent to the browser to hydrate it, which an autoplaying carousel needs anyway. For more on what the two directives do and do not do, see use client vs use server in Next.js.

Two fixes that do not apply here#

next/dynamic with ssr: false in the page. It is a common suggestion for "works in the browser, breaks on the server", but a Server Component may not use it. Next.js 16.4.0 stops the build before rendering anything:

text
Error: `ssr: false` is not allowed with `next/dynamic` in Server Components. Please move it into a Client Component.

The lazy loading guide states the same rule. Once the dynamic call is inside a 'use client' file you no longer need it for this error.

Updating the package. There is no newer version of react-responsive-carousel to update to, as shown above. Other carousels exist, but switching libraries is a bigger change than one wrapper file, and any package that extends React.Component without a 'use client' directive needs the same treatment.

The same cause with a different message#

Whether you see "Super expression" depends on how the package was compiled. A package that ships native class … extends React.Component syntax instead of the transpiled helper fails in a Server Component with the engine's own wording. A minimal CommonJS package with one such class, imported from a page on Next.js 16.4.0, gave:

text
Error: Failed to collect configuration for /
  [cause]: TypeError: Class extends value undefined is not a constructor or null

Adding 'use client' to the page fixed that build too. If the value in that message is [object Object] rather than undefined, the cause is usually different: a circular import hands the subclass an unfinished module, as covered in Cannot access 'Player' before initialization. The same "you imported something the server build cannot run" family also includes the compile-time react-dom/server import error in the App Router, which Next.js does catch before rendering.

The next error: a function prop across the boundary#

The wrapper is a Client Component, so every prop the Server Component page passes to it must be serialisable. Carousel props such as statusFormatter, renderArrowPrev or onChange are functions. Passing one from the page builds fine and then fails at prerender:

text
Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". Or maybe you meant to call this function rather than return it.
  {statusFormatter: function statusFormatter, children: ...}
                    ^^^^^^^^^^^^^^^^^^^^^^^^

The fix is to define the function on the client side. Turn the wrapper into a small 'use client' component that sets the function props itself and takes only data and children from the page:

jsx
// app/banner.js
'use client'
 
import { Carousel } from 'react-responsive-carousel'
 
export default function Banner({ children }) {
  return (
    <Carousel statusFormatter={(current, total) => `${current} / ${total}`}>
      {children}
    </Carousel>
  )
}

With the page rendering <Banner> and its slides, the build prerenders again. The same message can come from a root layout instead of a page; the Next.js 16 /_not-found prerender build error walks through that case, where a callback crosses into a Client Component that every route renders.

Reproduction details: every output above comes from clean Docker containers (official node:22-bookworm image, Node.js 22.23.3) on 10 October 2026, with Next.js 16.4.0 (React 19.3.0 installed, while the App Router renders with the copy bundled in Next.js, as explained above), react-responsive-carousel 3.2.23 and react-easy-swipe 0.0.21, plus a second project on Next.js 13.5.11 with React 18.2.0. The page and carousel files are the plain JavaScript versions shown here. If your build still fails after the wrapper, read the first line of the [cause]: when it names a different package, that package is the next class component to move behind a 'use client' file.

Further reading: Postmortem: The Next.js App Router Memory Leak of 2023.

Frequently Asked Questions

|

Have more questions? Contact us

Still stuck? Paste your error.

Paste the error message or stack trace — we check it against every fix and tool on the site.

Matching happens in your browser. When you search, a cleaned error signature is sent so we can spot errors we do not cover yet — never the raw text, your IP address or your e-mail. Do not paste passwords or keys. Details

Written by

Mahdi Ben Rhouma
Mahdi Ben Rhouma

Full-Stack Dev — Next.js & Supabase

Solo developer building SaaS products with Next.js and Supabase. Writing about production patterns the official docs skip.

Remote