getServerSideProps
and getStaticProps
In Next.js, data fetching methods play a crucial role in enabling server-side rendering (SSR), static site generation (SSG), and client-side data fetching for your React components. These methods allow you to fetch data from various sources (e.g., APIs, databases, external services) and use that data to pre-render pages or hydrate them on the client side.
In this article, we’ll explore the getInitialProps
, getServerSideProps
, and getStaticProps
data fetching methods. We’ll take a look at the role getInitialProps
played in previous versions of Next.js and the transition to newer and better data fetching methods.
Jump ahead:
getInitialProps
getServerSideProps
and getStaticProps
getServerSideProps
lifecyclegetInitialProps
in Next.js 13getServerSideProps
for performance in Next.js 13getInitialProps
to getServerSideProps
or getStaticProps
getInitialProps
getInitialProps
is a method used in older versions of Next.js (versions prior to 9.3) to fetch data on the server side before rendering a page. It was the primary data fetching method used in Next.js before newer data fetching methods like getServerSideProps
and getStaticProps
were introduced.
In older versions of Next.js, getInitialProps
was the primary data fetching mechanism for both SSR and client-side rendering. It allowed developers to perform custom data fetching logic for each page and pass the fetched data as props to the page component:
// In older versions of Next.js, you would define getInitialProps like this: import React from 'react'; const HomePage = ({ posts }) => { // Render the list of posts return ( <div> <h1>Latest Blog Posts</h1> <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); }; HomePage.getInitialProps = async () => { // Fetch data from an API const response = await fetch('https://api.example.com/posts'); const posts = await response.json(); // Return the data as props return { posts }; }; export default HomePage;
In this example, the getInitialProps
method fetches the list of blog posts from the API server-side. When a user visits the homepage, the server will pre-render the page with the fetched data and serve it as a complete HTML page. This approach helps with SEO, improves initial page load times, and ensures that the page has the necessary data before being served to the client.
getServerSideProps
and getStaticProps
The transition from getInitialProps
to getServerSideProps
and getStaticProps
in Next.js represented a significant improvement in data fetching and rendering strategies. This change was introduced to simplify data fetching, enhance performance, and provide better predictability in terms of when and where data is fetched.
Let’s start by looking at what the getServerSideProps
and getStaticProps
lifecycles are useful for, and how they each mark pages for rendering.
getServerSideProps
is a data fetching method that was introduced in Next.js 9.3. It is used specifically for server-side rendering (SSR). Unlike getInitialProps
, getServerSideProps
is only executed on the server side during the initial page request and not on subsequent client-side navigations. This change improves performance by reducing duplicate data fetching and provides better predictability of server-side data fetching.
getStaticProps
is another data fetching method that was introduced in Next.js 9.3, and it is used for static site generation (SSG). When using getStaticProps
, Next.js pre-renders the page at build time and fetches the data during the build process. The pre-rendered HTML pages are then served to users directly from the CDN, offering faster page loads and reducing server load.
These new data fetching methods ensured better performance by reducing unnecessary data fetching and improving the performance of your Next.js application by fetching data more intelligently. With getServerSideProps
, you know that data is fetched only during the initial server-side request, making it easier to understand when and where data is retrieved, and with getStaticProps
, the data will only be fetched at build time.
With the introduction of getStaticProps
and getServerSideProps
, Next.js users now have two different data fetching methods that are used to mark pages for rendering either at build time or upon each request respectively.
When a user requests a page that uses getServerSideProps
, the server will execute this function, fetch the data, and pass it as props to the page component. The page is then rendered on the server with the fetched data and sent to the client as a complete HTML page. This approach is known as server-side rendering (SSR), and it ensures that the page always has the most up-to-date data when accessed by users.
With getStaticProps
, you get the option to pre-render pages at build time, generating static HTML files with the fetched data. When you use getStaticProps
, Next.js runs the function during the build process (not on each request) and fetches the data needed for the page. The fetched data is then used to pre-render the page into a static HTML file, which is saved in the build output directory (e.g., the build
folder).
Now, when a user visits a page that was pre-rendered with getStaticProps
, Next.js serves the static HTML page directly from a CDN, improving page load times and reducing server load. This approach is called popularly known as static site generation (SSG), and it is ideal for pages with content that doesn’t change frequently.
getServerSideProps
lifecycleAs mentioned above, the getServerSideProps
lifecycle is used to fetch data on the server side and pre-render the page with the fetched data before sending it to the client. Unlike getStaticProps
, getServerSideProps
executes on each request, making it suitable for pages that require dynamic data or data that changes frequently.
The getServerSideProps
function takes a context object as a parameter that contains page data such as params
, res
, req
, query
, etc. Here’s a breakdown of how the getServerSideProps
lifecycle works:
getServerSideProps
, the server-side code is executed firstgetServerSideProps
function is called, and it fetches the necessary data from external APIs, databases, or other sourcesWhen compared to the getInitialProps
lifecycle, getServerSideProps
is much cleaner and more predictable in terms of fetching data, especially when it comes to context switching between server operations and client operations.
With getInitialProps
, operations were being executed on both the server and client side, which sometimes led to duplicate data fetching during client-side navigation. But with getServerSideProps
, there was a clear understanding that data fetching logic in the getServerSideProps
lifecycle would be executed only on the server side during the initial request, eliminating the duplicate data fetching that might occur with getInitialProps
.
Example use cases for getServerSideProps
:
getServerSideProps
to fetch the latest data on each requestgetServerSideProps
is well-suited for fetching this data securely on the server sidegetServerSideProps
can fetch the data for the specific route during each requestIn summary, getServerSideProps
offers a more straightforward and efficient way to fetch data on the server side, especially for pages that require server-side rendering and frequently changing data. It provides better control over data fetching, improved performance, and a smoother transition from the getInitialProps
lifecycle.
getInitialProps
in Next.js 13Despite the transition to newer data fetching methods, Next.js has maintained support for getInitialProps
for backward compatibility. This is because there might be existing projects that rely on getInitialProps
and transitioning all of them to the newer methods might be impractical in some cases.
To handle edge cases where getInitialProps
might still be necessary, consider the following scenarios:
getStaticProps
or getServerSideProps
, you might continue using getInitialProps
getInitialProps
getInitialProps
, it might be more practical to continue using it rather than rewriting everythinggetServerSideProps
for performance in Next.js 13getServerSideProps
runs on every request, which means that if you’re doing a lot of data fetching or computations, it can slow down your site. There are a few things you can do to optimize the use of getServerSideProps
for performance in Next.js 13.
One is to make sure you’re returning the required props
object with the props
property, which can help reduce the number of repetitive calls. When you call getServerSideProps
, Next.js creates a server-side request to fetch the data. This request can be quite expensive, especially if you’re doing a lot of computations. If you return the required props
object, Next.js will memoize the request and reuse the result for subsequent calls. This is important because it means that Next.js doesn’t have to make multiple requests to the server to get the same data, which can significantly improve performance.
Another way to optimize the use of getServerSideProps
in your project is by taking advantage of smarter caching. It works by caching the results of your request based on the content that was requested. For example, if a user requests a specific page, Next.js will only cache the data for that page. This means that if another user requests a different page, it won’t have to load the entire site from scratch, which can save a lot of time. This is different from traditional caching, which simply stores the entire site in a cache and serves it to all users.
Another benefit of smarter caching is that it allows for “incremental updates”. This means that if you make a small change to your code, only the affected parts of the site will be updated in the cache.
getInitialProps
to getServerSideProps
or getStaticProps
Migrating from getInitialProps
to getServerSideProps
or getStaticProps
involves updating your data fetching logic to the new data fetching methods introduced in Next.js. The migration process depends on whether you want to achieve server-side rendering (SSR) or static site generation (SSG). Here’s a detailed overview of the steps involved in the migration:
Migrating to getServerSideProps
(SSR):
getInitialProps
: If your page components use getInitialProps
, you need to remove it from those componentsgetInitialProps
with getServerSideProps
: Replace the getInitialProps
method with the getServerSideProps
method in your page components. The structure of getServerSideProps
is different from getInitialProps
, and it returns an object with the props
key containing the fetched datagetServerSideProps
, the fetched data will be automatically passed as props to the page component. You can access this data using the props
parameter of your page componentLet’s consider a simple example where you have a blog application, and you want to fetch a list of blog posts from an external API to display on the homepage:
// Before migrating from getInitialProps const HomePage = ({ posts }) => { // Render the list of posts }; HomePage.getInitialProps = async () => { // Fetch data from an API const response = await fetch('https://api.example.com/posts'); const posts = await response.json(); // Return the data as props return { posts }; }; // After migrating to getServerSideProps const HomePage = ({ posts }) => { // Render the list of posts }; export async function getServerSideProps() { // Fetch data from an API const response = await fetch('https://api.example.com/posts'); const posts = await response.json(); // Return the data as props return { props: { posts }, }; }
Migrating to getStaticProps
(SSG):
getInitialProps
: If your page components use getInitialProps
, you need to remove it from those componentsgetInitialProps
with getStaticProps
: Replace the getInitialProps
method with the getStaticProps
method in your page components. Like getServerSideProps
, the structure of getStaticProps
is different from getInitialProps
, and it returns an object with the props
key containing the fetched datagetStaticProps
, you can also include the revalidate
option in the returned object to specify how often the data should be revalidated and regenerated. This is useful when you want to update the data periodically without redeploying your applicationUsing the same example use case as above, here is our code before and after migrating from getInitialProps
and getStaticProps
:
// Before migrating from getInitialProps const HomePage = ({ posts }) => { // Render the list of posts }; HomePage.getInitialProps = async () => { // Fetch data from an API const response = await fetch('https://api.example.com/posts'); const posts = await response.json(); // Return the data as props return { posts }; }; // After migrating to getStaticProps const HomePage = ({ posts }) => { // Render the list of posts }; export async function getStaticProps() { // Fetch data from an API const response = await fetch('https://api.example.com/posts'); const posts = await response.json(); // Return the data as props return { props: { posts }, }; }
In summary, migrating from getInitialProps
to getServerSideProps
or getStaticProps
involves updating the data fetching logic and method signatures to improve performance, predictability, and context switching in your Next.js application. Depending on your use case, you can choose between getServerSideProps
for server-side rendering or getStaticProps
for static site generation.
Debugging Next applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Next.js app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your Next.js apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowDesign React Native UIs that look great on any device by using adaptive layouts, responsive scaling, and platform-specific tools.
Angular’s two-way data binding has evolved with signals, offering improved performance, simpler syntax, and better type inference.
Fix sticky positioning issues in CSS, from missing offsets to overflow conflicts in flex, grid, and container height constraints.
From basic syntax and advanced techniques to practical applications and error handling, here’s how to use node-cron.
6 Replies to "Data fetching in Next.js with <code>getServerSideProps</code> and <code>getStaticProps</code>"
I like the article
have one question how we can make api call in _app.js to get the data and pass over nav component
is this api call to a third party api or to one of the endpoints from the next app? Generally, unless the change is happening after the particular page loads (like data that relies on user input before making api call) I would just use getSeverSideProps or getStaticProps to make database calls instead of calling API endpoints.
yes …
I like this article and know I can understand the difference between getInitialProps & getServerSideProps
This is an older post, but I feel like Vercel/Next.js have done a pretty admirable job obscuring the valid reasons to still use getInitialProps. Even a lot of seasoned devs may not be aware that the original workflow most people used in earlier isomorphic/universal react apps pretty much assumed you had a separate and decoupled API. Its endpoints would be called from both client (navigation changes) and server (initial load or full browser refresh) using the same code via something like isomorphic fetch or axios.
There are both advantages and disadvantages to this pattern:
1. Your backend isn’t limited to Javascript/Typescript, it can be any language. Being decoupled, it’s easier when you have frontend/backend specialists.
2. If you have a mobile app, IoT or anything else besides a web browser a decoupled API is going to save a lot of time. These things don’t share a view layer but probably do share a data source.
While you can of course call a decoupled API endpoint in getServersideProps, it’s probably a bad idea because it adds an extra network hop when called from the client. Using the older pattern (getInitialProps in Next), you would be calling the final endpoint directly instead of “asking” the Next.js backend to do it.
3. getServersideProps as far as I know results in more requests to your server. getInitialProps can be cached, but from the documentation it seems that GSSP is always called on route changes even when the data was recently received and still valid.
The disadvantages are pretty well documented, but mostly avoidable if you know what you’re doing, (don’t import server only packages from isomorphic code, check for client when using browser APIs, etc).
This is not a recommendation to use getInitialProps. It is cleaner and easier to use the newer patterns for a lot of apps. They reduce complexities, but they also introduce others. There are plenty of people who will probably just choose a different framework now that Next doesn’t seem to want to support their use case.
These are experimental times for SSR/SPA fusion… IMO the newest patterns of islands and server components are an actual reason to be excited. It’s a bit of a mess ATM, but it will be interesting to see what it looks like once the dust settles.
All good ,but how the getServerSideProps is work inside the app in next.js 13