javascriptreactjsnext.jsstateloading

Loading page on nextjs 13


Hi im trying to get a loading page to show while website is taking the time to load. as it quite a large website I thought a loading screen would provide the best possible user experience however I cannot seem to figure out how to get it to work on nextjs 13. I have created a simple functional component that says loading... and have imported it directly into my layout.jsx folder.

I am using the app directory method which is quite new and im also new at nextjs so im a little lost ^^

I imagine I might need to set state at some point but I cant seem to figure out when and where to do it

any advice would be great.

thanks

import "./globals.css";
import React, { useState, useEffect } from "react";
import Loading from "../components/loading/loading";

const Layout = ({ children, dataLoaded }) => {
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (dataLoaded) {
      setLoading(false);
    }
  }, [dataLoaded]);

  return (
    <body className="app {oswald.className}">
      {loading && <Loading />}
      {children}
    </body>
  );
};

export default Layout;

. . .

Attempt 1 -

After following one of the answers below it does not seem like my loading page is showing up at all. and no errors showing up.

my layout is as follows

layout.jsx

import "./globals.css";
import { Suspense } from "react";
import Loading from "../components/loading/loading";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <head />
      <body>
        <Suspense fallback={<Loading />}>{children}</Suspense>
      </body>
    </html>
  );
}

LoadingPage.js

const LoadingPage = () => {
  return (
    <div className="loading w-screen h-screen bg-red-100">
      <p>Loading...</p>
    </div>
  );
};

export default LoadingPage;

Loading.js

import LoadingPage from "@/components/loading/loading";

export default function Loading() {
  return <LoadingPage />;
}

Solution

  • In NextJS 13, there's actually a default way to handle loading states within pages. You can declare a loading.tsx file in your /app directory, with this content:

    export default function Loading() {
      return <Loading />
    }
    

    Then, inside your Layout, you can wrap your page with a Suspense tag, like this:

    <Layout>
      <Navbar>
      ...
      <Suspense fallback={<Loading/>}>
        <Page/>
      </Suspense>
    </Layout>
    

    Your loading state will be automatically handled upon navigation.