Skip to content

Next.js error

The Default Export Is Not a React Component

The error

Error: The default export is not a React Component in "/products/[id]/page"

Next.js found the file and could not use what it exports. Four causes, and the build output tells you which one before you start guessing.

Files in the App Router are found by name, not by registration. page.tsx, layout.tsx, loading.tsx, error.tsx and not-found.tsx each have a contract, and this error means one of them was found and did not honour it.

Four causes cover essentially all of it.

1. A named export where a default is required

export function Page() { /* ... */ }        // not found
export default function Page() { /* ... */ } // found

The most common version, and the easiest to create while refactoring - moving a component between files and keeping the named export that worked there.

2. The default export is not a component

An object, a config, a string, or a function that returns something other than JSX. Also: export default async function is fine in the App Router, but export default function* or a class that does not extend React.Component is not.

Check what the function actually returns. A page that ends in a console.log and no return statement produces exactly this.

3. Two files claiming the same route

app/products/page.tsx and app/products/page.ts, or a page.jsx left behind after a rename to .tsx. The resolver picks one, and it may not be the one you have been editing - which is why the file on screen looks correct.

find app -name 'page.*' | sort | uniq -d -w -3

A leftover file after a migration is the usual source, and it survives because nothing else references it.

4. A barrel file in between

// app/products/page.tsx
export { default } from './product-page';

This is legal and usually works. It stops working when the re-exported module has no default, or when the chain passes through an index.ts that spreads named exports. Re-export chains are worth avoiding in route files specifically

  • the file that names the route should contain the component.

While you are in the file

Two adjacent contracts, since they produce their own errors:

error.tsx must be a Client Component. It receives an error object and a reset function, and it needs 'use client' at the top. Without it, the error boundary itself fails - and a broken error boundary is discovered during an incident.

generateMetadata and generateStaticParams are named exports, not default ones. Exporting either as default gives you a page that does not render and metadata that does not apply.

If this appeared during a migration

Pages Router files export components the same way, so a straight copy usually survives. What does not survive is getServerSideProps, getStaticProps and getInitialProps - they are ignored silently in the App Router rather than erroring, so a page that "works but has no data" is the companion symptom to this one. Migrating without a freeze covers the order that avoids both.

Related questions

The file looks fine. Why is it complaining?
In most cases it is a named export where a default is required, or a second file matching the same route. Both look correct in isolation.
Does this apply to layout.tsx and error.tsx too?
Yes. Every special file in the App Router has a required export shape, and error.tsx additionally must be a Client Component.