In this article we are going to learn about data fetching with getServerSideProps
and getStaticProps
getServerSideProps
You can export the function getServerSideProps
from a page on the server side.
The Next Js will then pre-render this page on every request using the data returned by the function getServerSideProps
This function runs on every request and is used for server side rendering. It fetches data on every request and that makes it a good choice for real time data rendering
This includes use-cases like real-time analytics dashboard, or use-cases where data returned by the server might changes in short periods of time
Here is the basic example:
export async function getServerSideProps(context) {
// Fetch data here
const data = await fetchDataFromAPI();
// Must return an object with props
return { props: { data } };
}
When to use getServerSideProps
getServerSideProps
should be used for use-cases, where the page must be pre-render with real time data. Here are some of the specific use cases
- User-specific data
- Dynamic Content
- Secure Data fetching
- Server Side computations
- Real time content
Choosing between getServerSideProps
or API Routes
The serverSideProps
as well as creating REST API endpoints fetch data from the server but they are both built for different purposes
- API Routes: You can create REST API that can be consumed by the client side and can work with any time of application not just NextJs
But the API do not help with pre rendering of data or SEO for your NextJs application
2. getServerSideProps: It is tightly coupled with page rendering also serves multiple purposes such as SEO, direct database access and rendering user-specific content.
Here are some of the decision factors that need to be taken in to consideration when deciding what to choose between the two
- Type of client like web or mobile
- Separation of concerns
- Rendering requirement
If you are looking for a React Native Chat SDK, you can consider DeadSimpleChat React Native SDK
Using getServerSideProps
with Edge API routes
What are edge api routes?
Edge API routes refer to the serverless functions that run closer to the edge (That is on specific geographical destinations) so as to be closer to the user
This is done by combining catching and faster data delivery. You can combine the getServerSideProps
with Edge API routes
example:
export const config = {
runtime: 'nodejs', // or "edge"
}
export const getServerSideProps = async () => {}
This is useful in the following use-cases
- Geo-targeting
- Low latency data fetching
- Caching Strategies
Fetching data on the client side with getServerSideProps
The practice of loading the data directly in the browser using javascript libraries usually after HTML has been rendered is called client sode data fetching
This is done mostly in Single Page applications and data fetching javascript libraries are used mostly Axios is preferable in this
Key features of Data fetching with client side libraries
- Lazy loading
- Dynamic behaviour
- Client Side rendering
Example with Axios
useEffect(() => {
fetch('/api/data')
.then(response => response.json())
.then(data => setData(data));
}, []);
Example: Data Fetching with Axios/ Rest API and getServerSideProps
In this example we are going fetch a list of todos from Rest API using the getServerSideProps
- Installing the Axios package
npm install axios
2. Creating the page component like so pages/todos/[category]/js
3. Implementing the getServerSideProps
import axios from 'axios';
export async function getServerSideProps(context) {
const { category } = context.params;
let todos = [];
try {
const response = await axios.get(`https://api.example.com/products?category=${category}`);
products = response.data;
} catch (error) {
console.error('Could not fetch products', error);
}
return { props: { todoss } };
}
const TodosPage = ({ todos }) => {
return (
<div>
<h1>Products</h1>
<ul>
{todos.map((product) => (
<li key={product.id}>
{todi.name} - ${product.price}
</li>
))}
</ul>
</div>
);
};
export default TodosPage;
getStaticProps
This function runs at build time, and as contract to getServerSideProps the data is fetched once during the inital build time. This makes is much more efficient and cacheable as compared to getServerSideProps.
But it is more useful for static sites or in use-cases where data does not change much frequently
Using the getStaticProps the Next.js pre renders the page using data returned by the getStaticProps
function during build time
The use cases includes blog posts or documentation basically anything that does not need to change frequently
here is an basic example:
export async function getStaticProps() {
// Fetch data here
const data = await fetchDataFromAPI();
// Must return an object with props
return { props: { data } };
}
When to use getStaticProps
Understanding the right use-cases for geStaticProps, you can gain significant benefits in SEO and efficiency plus rendering time
Here are some of the scenarios best suited for getStaticProps
1. Data is available at build time:
the data is available ahead of user request and it is static data ( that is the data does not change frequently) then getStaticProps
is a good choice
2. Using it with headless CMS :
If you are using a headless CMS then your data probably does not change much, when your data changes you can rebuild the site to update your static pages
If this is the usecase then it aligns well with getstaticpros funcionality
3. Pre-rendering for SEO
SEO benefits greatly from static pages as compared to dynamic pages, and if you are creating static pages for SEO puposes then getstatcprops is beneficial to you
4. If the data can be cached publicly
If the data can be cached publicly and it is not user specific or individually generated then also the getStaticProps
can be used
When does getStaticProps
run?
In this section we are going to understand when the getStaticProps
runs in specific conditions and configurations
- Runs on the server
- Runs during build time
- With Fallback: true
- With Fallback: blocking
- With Revalidate:
- On-demand Revalidation
- Incremental Static site generation
- No Access to incoming request
Real life example of using getStaticProps
to retrieve data form CMS
we are going to create a real life example where we are going to render a page using getStaticProps in NextJs
Here we have a page that is in the pages directory in nextjs pages/blog.tsx
export default function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}
export async function getStaticProps() {
// Call an external API endpoint to get posts.
// You can use any data fetching library
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
}
}
1. Blog component
The blog component takes posts
as a prop and then renders the unordered list of blog post like this
export default function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
);
}
2. getStaticProps
function
the async func getStaticProps fetches the data for the blog post title at build time
It is notable that the function runs on the server, which has the benefit that you can run database queries to retrieve the data
Here the function is using the fetch API to request data from the api end point
the fetched data is then parsed into JSON format and returned as posts prop to the Blog component
Additional context: There some additional porps and parameters that can be used like context
and revalidate
that you can use to achieve more complex use-cases like Increamental Static Regeneration
Comparing getServerSideProps
and getStaticProps
Execution Time | Request-time (server-side) | Build-time (server-side) |
---|---|---|
Server Load | Increases with each request | Minimal, CDN does most of the work |
Page Generation | Dynamic per request | Static, at build time |
SEO | Good, but depends on server speed | Excellent, thanks to pre-rendering |
Data Freshness | Always fresh | Can be stale, unless using ISR |
User-Specific Data | Possible | Not directly, unless using Middleware |
Caching | Server or third-party solutions | Built-in CDN caching via Next.js |
Caching Strategies
getServerSideProps
Server Level Caching:
Since the getServerSideProps
gets called on every re-render, you can cache it on the server itself as it cannot be cached on the client side because of the dynamic nature of the data
Third Party solutions
You can use redis or one of many caching libraries to cache the HTML and render it whenever a request comes in
HTTP Cache control
You can also consider using the built in cache control of HTML to cache the server response on the client or through intermediate caches
All these caching strategies are good and can be implemented. One consideration you have to make is the data might not get stale while it is cached in one form or another
getStaticProps
CDN caching:
Being static in nature the getStaticProps
can easily be cached in CDN or content delivery networks and relayed whenever needed
Incremental static regeneration
With ISR while the new fresh page is being built the server serves you the old stale page. Hopefully there aren't a lot of changes between the new one and the old one as we are using getStaticProps
So, the user gets snappy page load speed plus the newer data whenever its available
Time to live:
If you are using the CDN to server pages faster, you can use the revalidate
tag and specify a time after which the CDN cache will be invalidated and a new page needs to be generated
Advanced Use-Cases
We have learned about the getServerSideProps
and getStaticProps
and it is time now to learn their advanced use cases in an hybrid model
Where we are going to be data fetching using both these methods and learn how these methods interact with getStaticPaths
for dynamic routes
In some use cases we require but Static site generation and server side rendering depending on specific requirements of the user and where the user is inside the applications or even in the same page
for example: A blog post might render popular posts in real time according to the number of users reading the post in real time and might render the body of the post in static form
Let us consider another example where we are developing a e-commerce application where the product listings can be static because they don't change frequently but the cart needs real time data as customers edit hte cart contents
// getting the product information at build time
export async function getStaticProps({ params }) {
const product = await getProductById(params.id);
return {
props: { product },
revalidate: 2400,
};
}
// This part uses getStaticPaths for dynamic routes
export async function getStaticPaths() {
const paths = await getAllProductIds();
return {
paths,
fallback: 'blocking',
};
}
// The page component
export default function ProductPage({ product }) {
const [cart, setCart] = useState(null);
// Use client-side fetching for the dynamic cart data
useEffect(() => {
const fetchCart = async () => {
const cartData = await getCart();
setCart(cartData);
};
fetchCart();
}, []);
return (
<div>
{/* product details gotten through the static site */}
<h1>{product.name}</h1>
{/* real time fetched cart data */}
<h2>Your cart has {cart ? cart.length : 'the details are loading...'}.</h2>
</div>
);
}
here the getStaticProps
is used to fetch the static product details at build time and the getStaticPaths
pre generates the product pages
Need Chat API for your website or app
DeadSimpleChat is an Chat API provider
- Add Scalable Chat to your app in minutes
- 10 Million Online Concurrent users
- 99.999% Uptime
- Moderation features
- 1-1 Chat
- Group Chat
- Fully Customizable
- Chat API and SDK
- Pre-Built Chat
Here are some of our other articles that you might be interested in
- Data Fetching with React Suspense
- React Server Components with Next.JS
- Links in Next Js: A Detailed Guide
- CSV files with Node and PapaParse: The Complete Guide
Conclusion
In this article we learned about getServerSideProps
and getStaticProps
and similarities and differences along with examples for both
I hope you like the article and thank you for reading