Victor Ribero Guasch
Victor Ribero Guasch

Reputation: 347

Nextjs getStaticProps error when passing an object as prop instead of plain string

I hope you're doing fine 👋.

Playing around with the new internalization NextJS feature, I found out an error I was not expecting at all.

If I pass a plain string as prop from the getStaticProps to the Page Component everything works fine in the default locale, but if I pass down an object instead of a plain string, it breaks.

I leave both codes here.

The following code is the one that works fine 👇:

import { useRouter } from "next/dist/client/router";

export async function getStaticPaths() {
  return {
    paths: [
      { params: { name: `victor`, locale: "es" } },
      { params: { name: `victor`, locale: "en" } },
    ],
    fallback: true,
  };
}

export async function getStaticProps(context) {
  const { params } = context;
  const { name } = params;

  return {
    props: {
      name,
    },
  };
}

/*
 * ✅ The following URLs work
 * - localhost:3000/victor
 * - localhost:3000/en/victor
 * - localhost:3000/es/victor
 *
 * TypeError: Cannot destructure property 'name' of 'person' as it is undefined.
 */
export default function PageComponent({ name }) {
  const router = useRouter();
  return (
    <>
      <div>The name is: {name}</div>
      <div>Locale used /{router.locale}/</div>
    </>
  );
}

The following code is the one that DOESN'T WORK 👇:

import { useRouter } from "next/dist/client/router";

export async function getStaticPaths() {
  return {
    paths: [
      { params: { name: `victor`, locale: "es" } },
      { params: { name: `victor`, locale: "en" } },
    ],
    fallback: true,
  };
}

export async function getStaticProps(context) {
  const { params } = context;
  const { name } = params;

  return {
    props: {
      person: {
        name,
      },
    },
  };
}

/*
 * ✅ The following URLs work
 * - localhost:3000/victor
 * - localhost:3000/en/victor
 *
 * 👎 The following URLs DOESN'T work
 * - localhost:3000/es/victor
 *
 * TypeError: Cannot destructure property 'name' of 'person' as it is undefined.
 */
export default function PageComponent(props) {
  const router = useRouter();
  const { person } = props;
  const { name } = person;
  return (
    <>
      <div>The name is: {name}</div>
      <div>Locale used /{router.locale}/</div>
    </>
  );
}

Upvotes: 1

Views: 1200

Answers (1)

Danila
Danila

Reputation: 18516

It is because you are using fallback: true.

The page is rendered before the data is ready, you need to use router.isFallback flag to handle this situation inside your component:

  if (router.isFallback) {
    return <div>Loading...</div>
  }

Or you can use fallback: 'blocking' to make Next.js wait for the data before render the page.

More info in the docs

Upvotes: 2

Related Questions