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() { /* ... */ } // foundThe 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 -3A 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.
