Education
Senior Software Engineer
Last updated onJun 4, 2024
Last updated onJun 3, 2024
Server-side rendering (SSR) is a technique used to generate HTML on the server side rather than the client side. In Next.js, SSR allows you to fetch data on the server and pre-render the HTML before sending it to the client. This approach enhances performance and SEO by providing fully rendered pages to search engines and users.
Next.js provides the getServerSideProps function to fetch data on the server at the request time. This function ensures that your page component receives the data it needs when a user visits a particular page. The server-side code handles data fetching, ensuring that the data on the server is always up-to-date and consistent.
Improved Performance and SEO: By pre-rendering pages on the server, SSR delivers fully rendered HTML to the client, reducing load times and improving the user experience. Search engines can also index your content more effectively.
Dynamic Data Handling: Server-side rendering in Next.js is ideal for pages that need to display dynamic data. Since the data is fetched on the server, you can handle complex data fetching methods and ensure that the latest data is available when the page is loaded.
Context Object for Data Fetching: The getServerSideProps function receives a context object containing information about the request. This object includes dynamic route parameters, query string values, and more, enabling you to customize data fetching based on the specific request.
Seamless Integration with Page Components: By using getServerSideProps, you can fetch data and pass it directly to your page components. This ensures that your components have access to all the data they need to render the page correctly.
Support for Internal and External Resources: SSR in Next.js allows you to fetch data from internal APIs or external services, making it versatile for various use cases. Whether you need to query your database or call an external API, SSR has you covered.
Enhanced User Experience with Client-Side Navigation: While SSR provides the initial render of your pages, Next.js also supports client-side navigation, allowing for fast transitions between pages without requiring a full reload. This hybrid approach combines the best of both worlds: server-side rendering for the initial load and client-side navigation for subsequent transitions.
The getServerSideProps function in Next.js is used to retrieve data from the server during a request.To define this function, you need to export it from your page component file. This function runs on the server and allows you to fetch data, which is then passed as props to your page component.
1export async function getServerSideProps(context) { 2 // Fetch data here 3 const data = await fetchDataFromAPI(); 4 5 return { 6 props: { 7 data, // Will be passed to the page component as props 8 }, 9 }; 10} 11 12export default function Page({ data }) { 13 // Render your page component with the fetched data 14 return <div>{data}</div>; 15}
The context object is a key part of the getServerSideProps function. It provides information about the incoming request and includes the following properties:
params: Contains the route parameters for dynamic routes.
req: The HTTP request object.
res: The HTTP response object.
query: The query string parameters.
preview: Preview mode status.
previewData: Data set in preview mode.
locale: The active locale configured for internationalized routing.
defaultLocale: The default locale configured for internationalized routing.
You can use the context object to tailor your data fetching to the specifics of the request, ensuring that your page component receives the correct data.
Fetching data on the server with getServerSideProps ensures that your page is pre-rendered with the necessary data before it is sent to the client. This is particularly useful for dynamic data that needs to be up to date when the page loads. You can use various data fetching methods to retrieve data from internal or external sources.
1export async function getServerSideProps(context) { 2 const res = await fetch('https://api.example.com/data'); 3 const data = await res.json(); 4 5 return { 6 props: { 7 data, 8 }, 9 }; 10}
In this example, the data is fetched from an external API and passed to the page component as props. This approach ensures that the data is ready on the server side and minimizes client-side data fetching.
When using getServerSideProps, you can fetch data from both internal and external resources. This flexibility allows you to integrate various data sources into your application seamlessly.
Internal Resources: Fetch data from your own APIs or databases.
External Resources: Call external APIs or services to retrieve data.
For instance, if you need to fetch data from an internal API, you can do so within the getServerSideProps function:
1export async function getServerSideProps(context) { 2 const res = await fetch('https://internal-api.example.com/data'); 3 const data = await res.json(); 4 5 return { 6 props: { 7 data, 8 }, 9 }; 10}
By leveraging both internal and external resources, you can build robust applications that gather data from multiple sources, ensuring that your page components always have the latest data available.
In Next.js, the getServerSideProps method is an asynchronous function that retrieves data from the server before producing a page. To define this function, you use the async keyword, which allows you to write asynchronous code using await. This ensures that your data-fetching operations are completed before the page is rendered and sent to the client.
Here's an example of how to write an async getServerSideProps function:
1export async function getServerSideProps(context) { 2 // Fetch data from an API 3 const res = await fetch('https://api.example.com/data'); 4 const data = await res.json(); 5 6 // Return the fetched data as props 7 return { 8 props: { 9 data, 10 }, 11 }; 12} 13 14export default function Page({ data }) { 15 // Render the page component with the fetched data 16 return <div>{data}</div>; 17}
In this example, the data is fetched from an API and passed to the page component as props. This approach ensures that the data fetching happens on the server side, providing up-to-date data to the page component.
When dealing with dynamic routes, getServerSideProps can access dynamic route parameters through the context object. This allows you to fetch data specific to a particular page based on the route parameters.
Here's how to handle dynamic route parameters in getServerSideProps:
1export async function getServerSideProps(context) { 2 const { params } = context; 3 const { id } = params; 4 5 // Fetch data using the dynamic route parameter 6 const res = await fetch(`https://api.example.com/data/${id}`); 7 const data = await res.json(); 8 9 // Return the fetched data as props 10 return { 11 props: { 12 data, 13 }, 14 }; 15} 16 17export default function Page({ data }) { 18 // Render the page component with the fetched data 19 return <div>{data}</div>; 20}
In this example, the dynamic route parameter id is used to fetch specific data from an API. The fetched data is then passed to the page component, ensuring that the content is tailored to the dynamic route.
The getServerSideProps function can fetch data from various API endpoints and external services. This flexibility allows you to integrate data from multiple sources into your Next.js application.
Here's an example of fetching data from an external service:
1export async function getServerSideProps(context) { 2 // Fetch data from an external API 3 const res = await fetch('https://api.external-service.com/data'); 4 const data = await res.json(); 5 6 // Return the fetched data as props 7 return { 8 props: { 9 data, 10 }, 11 }; 12} 13 14export default function Page({ data }) { 15 // Render the page component with the fetched data 16 return <div>{data}</div>; 17}
By fetching data from external services, you can enhance your application with diverse data sources, providing richer content to your users.
The context object in getServerSideProps provides access to the request URL and query string parameters. This allows you to fetch data based on the query string values, tailoring the data to the specific request.
Here's an example of parsing the request URL and query string:
1export async function getServerSideProps(context) { 2 const { query } = context; 3 const { searchTerm } = query; 4 5 // Fetch data based on the query string parameter 6 const res = await fetch(`https://api.example.com/search?term=${searchTerm}`); 7 const data = await res.json(); 8 9 // Return the fetched data as props 10 return { 11 props: { 12 data, 13 }, 14 }; 15} 16 17export default function Page({ data }) { 18 // Render the page component with the fetched data 19 return <div>{data}</div>; 20}
In this example, the searchTerm query string parameter is used to fetch data from an API. The fetched data is then passed to the page component, ensuring that the content matches the user's search query.
When using getServerSideProps, you need to define and export your page component in a way that it can receive the fetched data. In Next.js, a page component is a React component that represents a specific page in your application. You define this component as you would any other React component and ensure that it is the default export from the module.
Here’s an example:
1// pages/[id].js 2 3import React from 'react'; 4 5const Page = ({ data }) => { 6 return ( 7 <div> 8 <h1>{data.title}</h1> 9 <p>{data.content}</p> 10 </div> 11 ); 12}; 13 14export default Page;
In this example, Page is a React component that expects to receive data as props. It’s exported as the default export from the module, making it the page component for the corresponding route.
To pass the fetched data to your page component, you use the props key in the object returned by getServerSideProps. This data is then available in the page component via the props parameter.
Here's how you can pass the data fetched in getServerSideProps to your page component:
1// pages/[id].js 2 3export async function getServerSideProps(context) { 4 const { id } = context.params; 5 const res = await fetch(`https://api.example.com/data/${id}`); 6 const data = await res.json(); 7 8 return { 9 props: { 10 data, 11 }, 12 }; 13} 14 15const Page = ({ data }) => { 16 return ( 17 <div> 18 <h1>{data.title}</h1> 19 <p>{data.content}</p> 20 </div> 21 ); 22}; 23 24export default Page;
In this example, the data fetched from the API is passed as props to the Page component. This ensures that the component has access to the data it needs to render.
Server-side data fetching happens during the request time on the server before rendering the page. This approach ensures that the page is pre-rendered with up-to-date data on the server and sent to the client as fully rendered HTML. This is useful for dynamic data that needs to be fresh every time a user visits the page.
Client-side data fetching, on the other hand, happens after the initial page load. This approach can be useful for fetching data that updates frequently without needing to reload the entire page. However, it can lead to a slower initial page load and a less optimal SEO performance compared to server-side rendering.
Here’s an example contrasting server-side and client-side data fetching:
Server-Side Data Fetching:
1export async function getServerSideProps(context) { 2 const res = await fetch('https://api.example.com/data'); 3 const data = await res.json(); 4 5 return { 6 props: { 7 data, 8 }, 9 }; 10} 11 12const Page = ({ data }) => { 13 return ( 14 <div> 15 <h1>{data.title}</h1> 16 <p>{data.content}</p> 17 </div> 18 ); 19}; 20 21export default Page;
Client-Side Data Fetching:
1import { useEffect, useState } from 'react'; 2 3const Page = () => { 4 const [data, setData] = useState(null); 5 6 useEffect(() => { 7 const fetchData = async () => { 8 const res = await fetch('https://api.example.com/data'); 9 const result = await res.json(); 10 setData(result); 11 }; 12 13 fetchData(); 14 }, []); 15 16 if (!data) { 17 return <div>Loading...</div>; 18 } 19 20 return ( 21 <div> 22 <h1>{data.title}</h1> 23 <p>{data.content}</p> 24 </div> 25 ); 26}; 27 28export default Page;
Static Site Generation (SSG) is another powerful feature of Next.js, where pages are pre-rendered at build time rather than on each request. This approach can be beneficial for content that doesn’t change frequently, providing fast load times and improved SEO without the need for server-side rendering on each request.
You can use getStaticProps to fetch data at build time:
1export async function getStaticProps() { 2 const res = await fetch('https://api.example.com/data'); 3 const data = await res.json(); 4 5 return { 6 props: { 7 data, 8 }, 9 }; 10} 11 12const Page = ({ data }) => { 13 return ( 14 <div> 15 <h1>{data.title}</h1> 16 <p>{data.content}</p> 17 </div> 18 ); 19}; 20 21export default Page;
In this example, the data is fetched once at build time and the page is pre-rendered with this data. This results in a static page that loads quickly and is optimized for SEO.
Next.js offers a preview mode that allows you to bypass the usual static site generation (SSG) and server-side rendering (SSR) to display draft content from a CMS or other data source. This is particularly useful when you need to preview changes before publishing them.
To enable preview mode, you can call res.setPreviewData inside an API route:
1// pages/api/preview.js 2 3export default (req, res) => { 4 res.setPreviewData({}); 5 res.writeHead(307, { Location: '/' }); 6 res.end(); 7};
When preview mode is enabled, the getServerSideProps function will have access to preview data via the context object. You can then use this data to fetch draft content:
1export async function getServerSideProps(context) { 2 if (context.preview) { 3 const previewData = context.previewData; 4 // Fetch draft data using previewData 5 const res = await fetch('https://api.example.com/draft'); 6 const data = await res.json(); 7 return { props: { data } }; 8 } 9 10 // Fetch published data 11 const res = await fetch('https://api.example.com/data'); 12 const data = await res.json(); 13 return { props: { data } }; 14} 15 16const Page = ({ data }) => { 17 return ( 18 <div> 19 <h1>{data.title}</h1> 20 <p>{data.content}</p> 21 </div> 22 ); 23}; 24 25export default Page;
In this example, if preview mode is enabled, the function fetches draft data; otherwise, it fetches published data.
Managing preview data sets involves ensuring that your getServerSideProps function correctly differentiates between preview and live content. This can be done by checking the context parameter:
1export async function getServerSideProps(context) { 2 const data = context.preview 3 ? await fetchDraftData(context.previewData) 4 : await fetchLiveData(); 5 6 return { 7 props: { 8 data, 9 }, 10 }; 11}
This approach allows you to handle multiple data sets, ensuring that the correct version of the content is displayed based on whether preview mode is active.
Next.js allows you to redirect users to different pages from within getServerSideProps using the redirect object. This is useful for handling situations where a page needs to redirect to another URL based on certain conditions.
1export async function getServerSideProps(context) { 2 const res = await fetch(`https://api.example.com/data/${context.params.id}`); 3 const data = await res.json(); 4 5 if (!data) { 6 return { 7 redirect: { 8 destination: '/not-found', 9 permanent: false, 10 }, 11 }; 12 } 13 14 return { 15 props: { 16 data, 17 }, 18 }; 19}
In this example, if the fetched data is not found, the user is redirected to a /not-found page. The redirect object specifies the destination and whether the redirect is permanent.
The notfound boolean in getServerSideProps is another way to handle cases where the data is not found. When set to true, it renders a 404 page automatically.
1export async function getServerSideProps(context) { 2 const res = await fetch(`https://api.example.com/data/${context.params.id}`); 3 const data = await res.json(); 4 5 if (!data) { 6 return { 7 notFound: true, 8 }; 9 } 10 11 return { 12 props: { 13 data, 14 }, 15 }; 16}
In this example, if the data is not found, the notFound property is set to true, causing Next.js to display the built-in 404 page.
Leveraging the power of getServerSideProps in Next.js allows you to create dynamic, efficient, and SEO-friendly applications. By understanding and implementing server-side rendering, handling preview modes, managing redirections, and optimizing data fetching, you ensure that your application delivers up-to-date data and a seamless user experience.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.