32

I'm working with Next.js, I tried accessing data but got this error:

Error: Error serializing `.profileData` returned from `getStaticProps` in "/profile/[slug]".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.

My code:

import { getAllBusinessProfiles } from '../../lib/api';

const Profile = ({ allProfiles: { edges } }) => {
    return ( 
        <>
          <Head>
            <title>Profile</title>
          </Head>

          <Hero />

          <section>
            {edges.map(({ node }) => (
              <div key={node.id}>
                  <Link href={`/profile/${node.slug}`}>
                    <a> {node.businessInfo.name} </a>
                  </Link>
              </div>
            ))}
          </section>

        </>
     );
}
 
export default Profile;

export async function getStaticProps() {
    const allProfiles = await getAllBusinessProfiles();
    return {
      props: {
        allProfiles
      }
    };
  }

getAllBusinessProfiles from api.js:

const API_URL = process.env.WP_API_URL;

async function fetchAPI(query, { variables } = {}) {
  const headers = { 'Content-Type': 'application/json' };

  const res = await fetch(API_URL, {
    method: 'POST',
    headers,
    body: JSON.stringify({ query, variables })
  });

  const json = await res.json();
  if (json.errors) {
    console.log(json.errors);
    console.log('error details', query, variables);
    throw new Error('Failed to fetch API');
  }
  return json.data;
}

export async function getAllBusinessProfiles() {
    const data = await fetchAPI(
      `
      query AllProfiles {
        businessProfiles(where: {orderby: {field: DATE, order: ASC}}) {
          edges {
            node {
              date
              title
              slug
              link
              uri
              businessInfo {
                name
                title
                company
                image {
                  mediaItemUrl
                  altText
                }
                highlight
                phone
                city
                country
                facebook
                instagram
                email
                website
                profiles {
                  profile
                  profileInfo
                }
                extendedProfile {
                  title
                  info
                }
              }
            }
          }
        }
      }
      
      `
    );
    return data?.businessProfiles;
};

What could be the error here? I used the getStaticProps method on Next.js but got the error above instead. Please, check. Thanks.

The error: Server Error Error: Error serializing .profileData returned from getStaticProps in "/profile/[slug]". Reason: undefined cannot be serialized as JSON. Please use null or omit this value.

I don't know what could cause this though.

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Adewale Perfect
  • 553
  • 1
  • 5
  • 12

13 Answers13

21

Add JSON.stringify when calling an asynchronous function that returns an object.

Try modifying your getStaticProps function like this.

export async function getStaticProps() {
    const profiles = await getAllBusinessProfiles();
    const allProfiles = JSON.stringify(profiles)

    return {
        props: {
             allProfiles
        }
   };
}

The JSON.stringify() method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.

Source: MDN

Aryan Beezadhur
  • 4,503
  • 4
  • 21
  • 42
Fernando
  • 211
  • 2
  • 4
  • 1
    Is there a way how to unserialize the data automatically without having to call `JSON.parse()` on the props in the component manually? – Qwerty Apr 02 '22 at 22:14
  • 1
    you can serialize and unserialize at the same time ```JSON.parse(JSON.stringify(profiles))```. this allows you to send a normal object to your component @Qwerty – Arian Nargesi Dec 28 '22 at 13:22
5

I had this issue using Mongoose and Next.js.

To solve it: I switched from convert require to import then wrapped my result in JSON.parse(JSON.stringify(result));.

Good: import mongoose from 'mongoose';

Bad: const mongoose = require('mongoose');

Aryan Beezadhur
  • 4,503
  • 4
  • 21
  • 42
Joshu
  • 460
  • 4
  • 14
3

I had the same issue when I was working with redux with next js and the reason was one of the fields in the default state I set it to undefined. Instead I used null:

const INITIAL_STATE = {
  products: [],
  loading: false,
  error: undefined,
  cart: [],
};

error:undefined was causing the error. Because "undefined" cannot be serialized:

export async function getStaticProps() {
    const allProfiles = await getAllBusinessProfiles();
    return {
      props: {
        allProfiles
      }
    };
  }

you are returning "allProfiles" which is the result of async getAllBusinessProfiles() which is either returning undefined, error or one of the fields of the returned object is undefined. "error" object is not serializable in javascript

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
  • 1
    I was trying to export boolean value `context.preview` from `getStaticProps` and whenever I exited the preview mode, the value came `undefined`. I simply returned `!!context.preview` and the error was resolved. – KeshavDulal May 27 '21 at 12:25
3

I had the same serialization error when accessing a Vercel system environment variable in getStaticProps.

Using JSON.stringify did not do the trick, but String() worked. My code:

export async function getStaticProps() {
  const deploymentURL = String(process.env.NEXT_PUBLIC_VERCEL_URL);

  return {
    props: {
      deploymentURL,
    },
  };
}

Thanks to this GitHub issue for the inspiration

1

Instead of using undefined, you have to use null as the value for your variables.

Note that the error shows you exactly which variable is using undefined as its value. Just modify its value to be null.

The value 'undefined' denotes that a variable has been declared, but hasn't been assigned any value. So, the value of the variable is 'undefined'. On the other hand, 'null' refers to a non-existent object, which basically means 'empty' or 'nothing'.

Source: [1]

Gabriel Arghire
  • 1,992
  • 1
  • 21
  • 34
0

I was having the same issue while trying to find a match in the array of data using the id. The issue I had was the items in the array had ids which were numbers while the value I was getting from params was a string. So all i did was convert the number id to a string to match the comparison.

export async function getStaticProps({ params }) {
  const coffeeStore = coffeeStoreData.find(
    (store) => store.id.toString() === params.slug[0]
  );
  return {
    props: {
      coffeeStore,
    },
  };
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
jac wida
  • 187
  • 1
  • 1
  • 8
0

In getStaticProps() function, after fetching your data it will be in json format initially, but you should change it as follow:

     const res = await fetch(`${APP_URL}/api/projects`);
     const data = JSON.parse(res);

now it will work.

vvvvv
  • 25,404
  • 19
  • 49
  • 81
0

install a package called babel-plugin-superjson-next and superjson and added a .babelrc file with these contents:

{
  "presets": ["next/babel"],
  "plugins": ["superjson-next"]
}

see this topic : https://github.com/vercel/next.js/discussions/11498.

Newon
  • 23
  • 4
0

I had a similar problem too where I was fetching data through apollo directly inside of getStaticProps. All I had to do to fix the error was add the spread syntax to the return.

    return {
    props: {
      data: { ...data }
    }
  }
0
return { props: { allProfiles: allProfiles || null } }
vvvvv
  • 25,404
  • 19
  • 49
  • 81
  • 2
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 24 '22 at 20:33
0

When you call api you should use try catch. It will resolve error.

Example:

import axios from "axios";
    export const getStaticProps = async () => {
        try {
            const response = await axios.get("http:...");
            const data = response.data;
            return {
                props: {
                    posts: data
                }
            }
        } catch (error) {
            console.log(error);
        }
    }

Hope help for you !

Kim Duyên
  • 23
  • 4
0

put res from API in Curly Brackets

const { res }  = await axios.post("http://localhost:3000/api", {data})
return { props: { res } }
-1

try this, it worked for me:

export async function getStaticProps() {
  const APP_URL = process.env.PUBLIC_NEXT_WEB_APP_URL;
  const res = await fetch(`${APP_URL}/api/projects`);
  const projects = await res.json();
  return {
    props: {
      projects: projects?.data,
    },
  };
}
Ahmed Bargady
  • 269
  • 4
  • 6