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

Viewed 11104

Using Nextjs and I've created an index.js in the /pages directory and created meta.js in the /components/meta/ directory.

As my app rebuilds I get the following error:

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

As seen below I am importing Meta correctly, it is also a default export. Curious where I'm going wrong.

pages/index.js

// import Head from 'next/head'
import Meta from '../components/meta/meta';

export default () => (
  <div>
    <Meta />
    <p>Hello world! Welcome to</p>
    <h1>Moonholdings.io</h1>
  </div>
)

components/meta/meta.js

import Head from 'next/head'

export default () => (
  <Head>
    <title>Moonholdings.io</title>
    <meta name="description" content="Your Cryptocurrency Portfolio" />>
    <meta name="keywords" content="cryptocurrency, crypto, portfolio, bitcoin, ethereum, holdings"/>
    <meta name="robots" content="index, follow" />
    <meta name="viewport" content="initial-scale=1.0, width=device-width" />
  </Head>
)

Project structure

enter image description here

3 Answers

I ran into the same error because the IDE's auto-import feature can only import the Head component from next/document.

Don't:

import { Head } from 'next/document';

This Head component is to be used in custom documents.

Do:

import Head from 'next/head'

This Head component is to be used in your pages.

Why doesn't my IDE import the correct Head component?

It's not your IDE's fault. Well, not exactly... the next/head component uses a default export. Default exports don't play well with auto-import. It's among the reasons why default exports are considered bad practice. Quite unfortunate that Vercel chose to allow them in their project.

I got the same error when importing "Link" with Curly Braces "{}" from "next/link" and using "<Link></Link>" as shown below:

import { Link } from 'next/link';

const Hello = () => {
  return (
    <Link href='/hello'>
      Hello
    </Link>    
  )
}

export default Hello;

So, I imported "Link" without Curly Braces "{}" then the error was solved:

// "{}" are removed from "Link"
import Link from 'next/link';

const Hello = () => {
  return (
    <Link href='/hello'>
      Hello
    </Link>    
  )
}

export default Hello;

Ah just figured it out, was a small typo.

<meta name="description" content="Your Cryptocurrency Portfolio" />>

After removing the extra > in my meta.js file, it worked.

Related