Blog>
Snippets

Server-Side Data Fetching with Loading Indicator

Implement getServerSideProps in Next.js 14 with a loading indicator when transitioning between pages that require server-side data fetching.
import { useState, useEffect } from 'react';
import Router from 'next/router';

function useLoadingIndicator() {
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const handleStart = (url) => url !== Router.asPath && setLoading(true);
    const handleComplete = (url) => url === Router.asPath && setLoading(false);

    Router.events.on('routeChangeStart', handleStart);
    Router.events.on('routeChangeComplete', handleComplete);
    Router.events.on('routeChangeError', handleComplete);

    return () => {
      Router.events.off('routeChangeStart', handleStart);
      Router.events.off('routeChangeComplete', handleComplete);
      Router.events.off('routeChangeError', handleComplete);
    };
  }, []);

  return loading;
}

export default useLoadingIndicator;
This is a custom hook that uses Next.js Router events to set a loading state. It listens for route changes and updates the loading state accordingly, which can be used to display a loading indicator.
import React from 'react';
import useLoadingIndicator from './useLoadingIndicator';

export default function Layout({ children }) {
  const loading = useLoadingIndicator();

  return (
    <div>
      {loading && <div className='loading-indicator'>Loading...</div>}
      {children}
    </div>
  );
}
This is a Layout component that includes the loading indicator. It uses the useLoadingIndicator hook to check if loading is true and displays a loading message or spinner if it is.
export async function getServerSideProps(context) {
  // Fetch data from external API
  const res = await fetch(`https://api.example.com/data`);
  const data = await res.json();

  // Pass data to the page via props
  return { props: { data } };
}

function Page({ data }) {
  // Render data
  return <div>{data && data.content}</div>;
}

export default Page;
This getServerSideProps function fetches data from an external API on the server side and passes it to the Page component via props. It should be used in a page component file where server-side data fetching is required.