# React: “Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined”

> React says Element type is invalid: expected a string or a class/function but got: undefined. Usually a default vs named import mix-up. How to find it.

Canonical: https://app369.com/fix/react-element-type-is-invalid/
Last updated: 2026-11-08

The page goes blank and the console says Element type is invalid … but got: undefined (sometimes got: object), followed by You likely forgot to export your component from the file it’s defined in, or you might have mixed up default and named imports. React tried to render a component, and the thing you gave it was not a component. Almost always an import brought in undefined: the file exports the component one way and you import it the other way, or it doesn’t export it at all.

**Short answer**

Read the line under the error: Check the render method of X names the component that renders the broken one. In that file, check each import against its source file. export default Button is imported as import Button from './Button'; export function Button is imported as import { Button } from './Button'. Mixing them gives undefined. got: object usually means import * as, a package whose component sits under .default, or an object (not a component) being rendered.

## **Why the component came in as undefined, and the fix**

1. 01 ### **Default and named imports mixed up**
  > “You will get an error if you try to import a default export the same way you would a named export!” [**React, Importing and Exporting Components**](https://react.dev/learn/importing-and-exporting-components) Curly braces import a named export; no braces import the default export. Use the form that matches how the file exports it, or change the export.```
// Button.jsx
export default function Button() { /* ... */ }

// breaks: Button is undefined
import { Button } from './Button';

// works
import Button from './Button';
```
2. 02 ### **The component was never exported** A component written in a file without export, or exported under a different name after a rename, imports as undefined. Open the file and check the export line matches the name you import. TypeScript and ESLint’s import/named rule flag this before it runs. Also check the letter case of the file name: import Button from './button' works on a Mac but fails on Linux build servers such as Netlify or Vercel when the file is Button.jsx.
3. 03 ### **A package that changed its exports** After a major upgrade, a library may move a component or switch from a default to a named export (React Router’s Switch is one example). Check the library’s changelog for the version you installed, and import the name it now exports. If the import works but is an object with a default key, use the .default or the named export instead.
4. 04 ### **Next.js: a component across the server and client boundary** In the App Router, a client-only library imported into a Server Component can arrive as undefined. Put "use client" at the top of a small wrapper file that imports the library, and render that wrapper. next/dynamic, like React.lazy, needs a module whose default export is the component.
5. 05 ### **React.lazy pointing at a named export**
  > “Using this pattern requires that the lazy component you’re importing was exported as the default export.” [**React, lazy**](https://react.dev/reference/react/lazy) lazy() renders the default export of the module it loads. If the component is a named export, map it to default in the import.```
// Chart.jsx exports: export function Chart() {}
const Chart = lazy(() =>
  import('./Chart').then((m) => ({ default: m.Chart }))
);
```

Checked against the vendor’s docs on November 8, 2026: [React: Importing and Exporting Components (default vs named exports)](https://react.dev/learn/importing-and-exporting-components); [React reference: lazy](https://react.dev/reference/react/lazy).

## **Rather hand it over?**

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

- [from $450**App Fix Ticket**One reproducible bug in an existing mobile or web app, diagnosed and fixed.**See scope and start**](https://app369.com/fixed-price/flutter-firebase-bug-fix/)
- [from $450**AI-Built App Rescue**A Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.****No issues worth fixing, no charge.**** If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.**See scope and start**](https://app369.com/fixed-price/ai-app-rescue/)

Related: [**React Router “Switch is not exported from react-router-dom”**](https://app369.com/fix/react-router-switch-is-not-exported/) · [**React “Objects are not valid as a React child”**](https://app369.com/fix/react-objects-are-not-valid-as-a-react-child/) · [**React “Invalid hook call”**](https://app369.com/fix/react-invalid-hook-call/)

Questions

## **More on this error**

<details>

<summary>**How do I find which import is wrong? **+</summary>

The message ends with Check the render method of a component name. Open that component and log each imported component (console.log(Button)); the one that prints undefined is the bad import.

</details>

<details>

<summary>**Can a circular import cause it? **+</summary>

Yes. If two files import each other, one of them can read the other’s export before it is defined, so it gets undefined. Move the shared piece into a third file.

</details>

<details>

<summary>**Can you fix it for me? **+</summary>

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

</details>

A different error?

## **Describe it and get a written quote**

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.

[**Describe your problem **→](https://app369.com/contact/) [**All fixes**](https://app369.com/fix/)