#How to add a loader to wait the page in NextJS 13 using pages router and getServerSideProps
1 messages · Page 1 of 1 (latest)
In Next.js, you can create a loading state while fetching data in a page that uses getServerSideProps. However, the loading file convention you mentioned is specific to Next.js 13's app directory and is not available in the pages directory.
For a page that uses getServerSideProps, you can manage the loading state within the component itself. Here's an example based on the extracts:
import { useState, useEffect } from 'react';
const Profile = ({ user }) => {
const [loading, setLoading] = useState(!user);
useEffect(() => {
if (user) {
setLoading(false);
}
}, [user]);
if (loading) {
return <p>Loading...</p>;
}
return (
<div>
<h1>Your Profile</h1>
<pre>{JSON.stringify(user, null, 2)}</pre>
</div>
);
};
export async function getServerSideProps(context) {
// Fetch your data here
// For example, from a session
const user = context.req.session?.user || null;
return {
props: { user }, // Will be passed to the page component as props
};
}
export default Profile;
In this example, we're using React's useState and useEffect hooks to manage a loading state. When the component first renders, loading is true if there's no user prop, and a loading message is displayed. Once the user prop is available, loading is set to false, and the user's profile is displayed.
Remember, this is a simple example and might not cover all your use cases. You might need to adjust it based on your application's needs.
For more information, you can refer to the Next.js documentation on Server-side Rendering (https://nextjs.org/docs/pages/building-your-application/rendering/server-side-rendering) and getServerSideProps (https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props).
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@sonic nova kapa.ai is still learning and improving, please let us know how it did by reacting below
@jaunty ivy This solution doesnt work because the page will not be redered before gettting props from the server
Let me check the knowledge base for you. One moment! :books:
You're correct. In Next.js, when using getServerSideProps, the page will not render until the data fetching is complete. This is because getServerSideProps is designed to fetch the necessary data server-side before rendering the page.
The loading file convention you mentioned is a feature of Next.js 13's new routing with the app directory, which allows for streaming server-side rendering. This feature enables you to show an instant loading state from the server while the content of a route segment loads. However, this feature is not available in the pages directory.
Here's an example of a loading file from the extracts:
export default function Loading() {
return <p>Loading...</p>;
}
If you want to use this feature, you would need to structure your application to use the new app directory and routing features of Next.js 13.
For more information, you can refer to the Next.js documentation on Loading UI and Streaming (https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming) and Next.js on Vercel (https://vercel.com/docs/frameworks/nextjs).
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@sonic nova kapa.ai is still learning and improving, please let us know how it did by reacting below
@jaunty ivy I can´t do this, I have a big project and I can´t do this migration easily, I want to know how do this but in PAGES ROUTER
Let me check the knowledge base for you. One moment! :books:
I understand your situation. In the pages directory with getServerSideProps, you can't directly show a loading state from the server as you can with the app directory in Next.js 13. However, you can implement a client-side loading state.
One way to do this is by using a state management library like Redux or React's Context API to manage a global loading state. When you navigate to a new page, you can set this global loading state to true, and then set it back to false once the data has been fetched.
Here's a simplified example using React's Context API:
First, create a LoadingContext:
import React from 'react';
export const LoadingContext = React.createContext();
export const LoadingProvider = ({ children }) => {
const [loading, setLoading] = React.useState(false);
return (
<LoadingContext.Provider value={{ loading, setLoading }}>
{children}
</LoadingContext.Provider>
);
};
Then, wrap your application in this LoadingProvider:
import { LoadingProvider } from './LoadingContext';
function MyApp({ Component, pageProps }) {
return (
<LoadingProvider>
<Component {...pageProps} />
</LoadingProvider>
);
}
export default MyApp;
In your page, you can use setLoading before and after getServerSideProps:
import { useContext } from 'react';
import { LoadingContext } from '../LoadingContext';
const Page = (props) => {
const { loading } = useContext(LoadingContext);
return (
<div>
{loading ? 'Loading...' : 'Your content'}
</div>
);
};
export async function getServerSideProps(context) {
const { setLoading } = context;
setLoading(true);
// Fetch your data here
const data = await fetchData();
setLoading(false);
return {
props: { data }, // Will be passed to the page component as props
};
}
export default Page;