Aleister Crowley
Aleister Crowley

Reputation: 761

Infinite suspense loading while fetching data server side in Next with App router

I have a following problem: while trying to fetch some data server side in Next with App router, I am faced with an endless suspense loading. I think this must be somehow related to the data fetching, because when I remove that part, the component loads correctly. Am I doing something wrong here?

This is my server side component:

import Button from "@/components/Button";

interface EmailResetPreviewData {
  existingEmail: string;
  newEmail: string;
}

const getEmailResetPreview = async (emailResetId: string) => {
  const response = await fetch(
    `${process.env.NEXT_PUBLIC_API_BASE_URL}/auth/reset/email/preview/${emailResetId}`,
    {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
      },
    }
  );
  const data: EmailResetPreviewData = await response.json();
  return data;
};

const ResetEmail = async ({
  params,
}: {
  params: {
    emailResetId: string;
  };
}) => {
  const { emailResetId } = params;
  const data = await getEmailResetPreview(emailResetId);

  return (
    <div>
      <h1>Confirm Your New Email</h1>
      <p>
        Your current email is <strong>{data.existingEmail}</strong>.
      </p>
      <p>
        Your new email will be <strong>{data.newEmail}</strong>.
      </p>
      <Button>Change Email</Button>
    </div>
  );
};

export default ResetEmail;

that ResetEmail component is being rendered inside the following layout:

<html lang="en">
      <Suspense fallback={<Loading containerSize={150} barWidth={5} />}>
        <AuthProvider>
          <body className={`${comfortaa.className} ${styles.RootLayout}`}>
            <NavigationBar visible={navbBarVisible} />
            <div className={styles.pageContent}>{children}</div>
            <Footer />
          </body>
        </AuthProvider>
      </Suspense>
    </html>

Upvotes: 0

Views: 655

Answers (1)

Mateo Jacques
Mateo Jacques

Reputation: 1

I'm pretty sure the "endless suspense loading" has to do with your API call not resolving correctly. Did you check the console for information related to this request?

Besides that, it seems that you are trying to use Suspense on your entire layout (including the body of your html). Altough that may work in some cases, it's not how Next intends you to use Suspense.

If what you want is to show your Loading component while any request is still loading, Next 13 introduces the special file loading.js (.ts or .tsx on Typescript). Internally, Next is going to wrap the children on the layout with a Suspense, rendering the loading file content as a fallback.

So, when does Next want us to use Suspense manually? When you don't want to stop rendering your entire page as a request is loading, but only a part of the page that is affected by that. In that case, you would define your own Suspense boundary by wrapping only the asyncronous component which contains the request in a Suspense component, which means only that component will be replaced with the fallback until it finishes loading. This is what Next calls Streaming.

Please refer to the docs for more information on this matter: https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming

Upvotes: 0

Related Questions