getServerSideProps vs fetching directly in React - reactjs

I am getting a bit confused with the getServerSideProps of NextJS.
In the docs you can find this explanation.
For example, suppose that your page needs to pre-render frequently
updated data (fetched from an external API). You can write
getServerSideProps which fetches this data and passes it to Page
My confusing is why would you use getServerSideProps if you could simply fetch the data every x sec in your React component itself (after getting the initials data via getStaticProps).
Is there an advantage of using getServerSideProps over just the React way ?
so like this for example :
useEffect(() => {
const interval=setInterval(()=>{
const fetchdata = async () => {
const res = await fetch("url")
const data = await res.json()
setsongs(data)
}
fetchdata()
},15000)
return()=>clearInterval(interval)
}, [])

Due to the documentation, getServerSideProps fetches the API data on every request. So, there is a difference between requesting with a time interval ( like you mentioned in the react version), or using getServerSideProps.
Also, remember that getServerSideProps is implemented on the server-side and might be useful in cases that SEO is important. However, if the server goes down in the cases that you use getServerSideProps the whole page would not be served anymore.
https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering
Meanwhile, Fetching data on the client side (or the React way) is useful when SEO is not relevant, the page doesn’t need to be pre-rendered.
https://nextjs.org/docs/basic-features/data-fetching#fetching-data-on-the-client-side
In my opinion, it would be better if you use getServerSideProps when the displayed data is changing frequently and the user should see the most updated one, SEO is vital and a longer Time to first byte (TTFB) is acceptable.

There are useCases for all of them. You can use useEffect if SEO is not a concern and you want data to be updated in real-time.
You can use getServerSideProps when you want to have a better SEO ranking in your page.
Sure You can use getStaticProps which is way faster but know that getStaticProps is best used if your page contents don't change and stay the same like in a e-commerce website's product detail page.

Related

NextJS - conditionally pull data from an external API with getServerSideProps

I need to pull data from an external third-party API, and the request to the API has to come from the server-side rather than the client-side (the API will reject client-side requests).
I'm looking to use getServerSideProps, since according to the NextJS API it " only runs on server-side and never runs on the browser" which is exactly what I need.
However, once I pull the data from the API, I won't need to re-pull the data for another 15-30 minutes. During that time, I would use the previous response.
For this, swr sounds good, since it can be made into a reusable hook and "there will be only 1 request sent to the API, because they use the same SWR key and the request is deduped, cached and shared automatically."
The page's flow would look like:
User navigates to page and requests data
If the data does not already exist from a prior pull, use getServerSideProps to pull and store the data
If the data does exist and was pulled within the last 30 minutes, use swr (or some other method) to call an internal API and process the existing data, thereby avoiding another external API request.
The problem with this is getServerSideProps "must be exported as a standalone function — it will not work if you add getServerSideProps as a property of the page component", and it will run every time the page is requested.
Is there a way I can use getServerSideProps but only run it conditionally? Or is there another way that is more appropriate for this situation?
use getStaticProps which only runs during build-time. HTML will be created and will be placed into cache. when first request comes, html will be served from the cache
export async function getStaticProps(context) {
const data = await fetchData(args);
return {
props: {
// make sure you do not return undefined. it does not get serialized
myProp: data,
},
// first request will be returned from cache
// then data will be revalidated and cache will be updated
revalidate: 10*60, // In seconds. 10 minutes
};
}

Why do we need both "useParams" and "getAPI"?

From my understanding, useParams hooks would allow me to take parameter from another route.
Why then do we need to do axios.get as well, to make the fetching work?
Isn't it also just fetching the data (params) available on an API?
See picture for examples.
Thank you, I appreciate your time.
Sorry I can't really follow your use case.
useParams() is a hook from react-router and its sole purpose is to return dynamic params from the current rendered URL in your React application. What you do then with this value is up to you and, of course, you can use it as a param to fetch data from an external API. But this fetching has nothing to do with useParams() (or react-router), you do that with axios or fetch() or whatever. useParams() doesn't make any AJAX call.
Apparently in your specific case the value of the id param in your rendered React route is the same value you use on a API (jsonplaceholder.typicode.com/posts) to retrieve a resource. That's fine, but it's a peculiarity in your application design and doesn't change the fact that the two params (the one in your rendered route and the one passed to the external API) are different, unrelated things.

Next.js: what is the difference between using the "revalidate" option in the getStaticProps and using the SWR package?

Next.js has this "revalidate" option out of the box:
export async function getStaticProps(context) {
const data = await getData();
if (!data) {
return {
notFound: true,
};
}
return {
props: { data },
revalidate: 60,
}
}
The above code will make sure that a page is regenerated after 60 seconds from the moment we requested the updated data (first refresh to make a request for the new data, second refresh to update page). This is based on the Incremental Static Regeneration, so the site doesn't need to be rebuilt.
From the SWR docs:
If your page contains frequently updating data, and you don’t need to
pre-render the data, SWR is a perfect fit and no special setup needed:
just import useSWR and use the hook inside any components that use the
data.
So, does it mean that in this case, useSWR is basically the same as the next.js "revalidate" option? It seems to be doing the same thing but how often does the revalidation occur then? Is there any advantage to using one over the other?
No, they are not the same and fit different use-cases.
useSWR is a data fetching hook that provides caching and automatic revalidation mechanisms (which you can control) to keep the data fresh on the client-side. The data revalidation will happen on the client and will only benefit that single user.
Using revalidate and Incremental Static Regeneration allows you to regenerate static pages on the server-side. The entire page gets generated again on the server and is statically cached. Any subsequent requests (from any user) will be served the regenerated page.
Using one or the other depends entirely on your requirements, and they're not mutually exclusive - you can use both at the same time.

Best way to paginate data with Firestore and Next.js for SEO

I use only firestore admin to access the database.
I have a function to retrieve the data from firestore. Given a collection name and option parameters (orderBy, startAt, endBefore, limit or limitToLast), it returns the resulting data in an array as well as a string with the url for the next page query and another one for the previous page. Something like this:
export interface FirestorePaginatedResponse {
data: any[],
nextParams?: FirestoreQueryOptions,
prevParams?: FirestoreQueryOptions,
}
export async function paginatedQuery(
collectionPath: string,
basePath: string,
options: FirestoreQueryOptions,
) {
[...]
return {
data,
nextParams,
prevParams,
}
}
So, considering that Static Page Rendering is not an option for Firestore pagination, what would be best for SEO A or B?
A. Do the pagination client side. One landing page with getStaticProps to load the initialData, and then use useSWR hook to retrieve and prefetch the data client side for the next pages. With useSWR probably we would save some reads to firestore due to caching and due to static generation the loading time of the first page would be faster.
B. Do the pagination with server side rendering. The landing page would have a getServerSideProps function to load the data directly given the query parameters before the page is rendered. I think that server rendering might be better for SEO, but maybe the loading of the page would be slower.
In any of those cases the query parameters are read from the url, and the pages are navigated using next/link with href to do the client transition between pages.
EDIT:
I tested 2 pages for pagination with the same content one with getServerSideProps and another one with getStaticProps. The initial loading time of the page is almost the same, so I think I'll be going with the server side rendering as xBurnsed said, for SEO it's better ssr than csr.
As far as I am concerned, the best approach for pagination when it comes to Firestore is to start at the first page, and then cycle through the results using startAfter() with the info of the doc where the last page ended. You can find more information in the following documentation.
Since pagination is meant to prevent loading all documents, I would choose to fetch the documents for each page on demand using the above described method.
Server-side rendering is considered a better option for SEO than client-side rendering. This is because server-side rendering can speed up page load times, which not only improves the user experience, but can help your site rank better in Google search results.
Server-side rendering is also better for SEO because it removes the burden of rendering JavaScript off of search engine bots, which makes it faster for them. Also, not all search engine bots are able to run JavaScript, as stated here.

SWR vs Isomorphic-unfetch for data fetch Next.Js?

While reading the Next.Js tutorial in the Routing API I learned about fetching data with these 2 libs.
The fetch object from Isomorphic-unfetch, is used within the getInitialProps async function to call an external API. Then in the Route API part, the SWR along with the { useRouter } from 'next/router; shapes the call to an internal API developed within the same Next.Js server with a lot of flexibility to query the req params.
Other than these 2 aspects, what other differences are between these 2 approaches?
isomorphic-unfetch allows you to make fetch calls on both the client and the server, which is why it's shown in examples that use getInitialProps.
Generally speaking, you fetch data on the server using getInitialProps. This will be blocking – meaning the markup will not be returned until your data has been fetched. Consider a product page for an e-commerce site. It's important that we return the product name, price, and other information from the server and not on the client-side.
SWR is similar, but a bit different. It first returns the data from cache (stale), then sends the fetch request (revalidate), and finally comes with the up-to-date data again. A real-world example of where you'd use something like SWR is on a dashboard page. You don't want to fetch all the data in getInitialProps in a blocking manner, so you render out the dashboard "shell" in a loading state, and then use SWR to fetch the data client side. You can view an example of this here.
Source - Creator of Mastering Next.js 😄

Resources