Checkout my CSS Grid By Example and Getting Started With React video courses on Skillshare. Sign up now and get one free month of Skillshare.

How to show an animated loading indicator in NextJs 13

The scope of this article is to show how to add a loading indicator in Nextjs 13, while waiting for the response of an HTTP request.

We have seen in the previous article how to do a simple GET request with NextJs 13.

Will take the same example, but will add an intentional 5s delay to the response to the request so that the loading indicator becomes much clear:

import Article from "./article"

const api = 'https://jsonplaceholder.typicode.com/posts'

const delayFetch = (url, options) =>
  new Promise((resolve) => {
    setTimeout(() => resolve(fetch(url, options))
    , options.delay)
  })

const loadDataFromServer = async ()=> {
    const response = await delayFetch(api, {delay: 5000})
    return response.json()
}

export default async () => {
    const articles = await loadDataFromServer()
    return (<>
        <h1>My blog</h1>
        {articles.map( p => <Article key={p.id} {...p}/>)}
    </>)
}

With this in place, when the users first visit the page they will see just an empty page for, at least, 5 seconds:

Using the loading.js file in NextJs 13

One of the new features of NextJs 13 is a very simple way to add loading indicators for our pages. Working in the convention over configuration fashion, all we need to do is to add a loading.js file in the same folder as the page.

The loading.js will need to export a React component that will be shown to the user while that page loads.

In our case, given that we just have the root app/page.js we will place the loading file directly in the app directory:

// app/loading.js
export default function Loading() {
  return <div>App is loading ...</div> 
}

And now, if we visit http://localhost:3000/ we will first see our loading component:

Adding the loading animation

With the loading indicator in place, we can use some styled JSX to add a loading animation on the screen:

export default function Loading() {
  return <>
    <style jsx>{`
        .loader {
          border: 16px solid #f3f3f3; 
          border-top: 16px solid #3498db;
          border-radius: 50%;
          width: 120px;
          height: 120px;
          animation: spin 2s linear infinite;
          margin: auto;
        }

        @keyframes spin {
          0% { transform: rotate(0deg); }
          100% { transform: rotate(360deg); }
        }
    `}</style>
    <div class="loader"></div> 
  </>
}

Our loading indicator will now look like this:

You can download the full code here.

Having multiple loading.js files in NextJs 13

Keep in mind that you can set loading files for each page in our app.

For example, if we add 2 new pages http://localhost:3000/blue and http://localhost:3000/red we can set custom loading pages for each of them:

/app
    /blue
        loading.js
        page.js
    /red
        loading.js
        page.js
    loading.js
    page.js

NextJs will first look in the directory of the requested page for a loading file, and only if it does not find it there it will search in the parent directory for one.

In the following article, we will see how to use React Suspense for showing loading indicators in NextJs.

Home Screencasts Best of Newsletter Search X