How to retrigger getStaticProps after an update? - reactjs

On a personal project related to an online shopping website I have a list of the products page, I'm trying that after I delete a product to refetch the products. I'm using Next.JS and Firebase as a database.
The first time when the page is loaded I'm getting the products with getStaticProps
export const getStaticProps = async (context) => {
const items = Array.from(await getItems({shouldShuffle: false}));
// more code + return items
}
How can I recall the items var after deleting a product to refetch items?

You can investigate using On-demand Revalidation (Beta), which allows you to manually purge the Next.js cache for a specific page.
This only works for v12.1.0 or more. If you're in a previous version, you will not be able to purge/bust the cache unless you either redeploy or set a revalidate property that specifies the seconds after which an automatic page re-generation will occur.

Related

How can I dynamically generate pages in Next.js using data from a custom API endpoint, while maintaining the key features

How can I dynamically generate pages in Next.js using data from a custom API endpoint, while maintaining the key features provided by Next.js such as automatic code splitting, optimized performance, and SEO optimization?
Here's an example scenario: let's say I have an e-commerce website built with Next.js, and I want to dynamically generate a product detail page for each of the items in my product catalog. The product information is stored in a database and can be accessed through an API endpoint at https://my-api.com/products/:id, where :id is the ID of the product.
To accomplish this, I need to be able to call the API endpoint in my Next.js application and pass the product information to a component that will render the product detail page. At the same time, I want to take advantage of the benefits provided by Next.js, such as automatic code splitting, which means that the JavaScript, CSS, and other assets for the product detail page should only be loaded when the user navigates to that page, and not when the user visits other pages on the site.
What is the best way to implement this functionality in Next.js, while preserving the automatic code splitting, optimized performance, and SEO optimization provided by the framework?
Here's an example of what the code for the product detail page may look like:
import React from 'react'
import axios from 'axios'
function ProductDetail({ product }) {
return (
<div>
<h1>{product.name}</h1>
<p>{product.description}</p>
<p>Price: {product.price}</p>
</div>
)
}
ProductDetail.getInitialProps = async (ctx) => {
const { id } = ctx.query
const res = await axios.get(`https://my-api.com/products/${id}`)
const product = res.data
return { product }
}
export default ProductDetail
You can follow the guide on Next.js Dynamic Routes. Imagine you want to handle a blog with many posts where each post has it's own unique slug.
Then you would dynamically handle unknown slugs using this literal filename:
pages/post/[...slug].js

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
};
}

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.

Next.js : getStaticProps with context API

I'm currently building my first next app (e-commerce with Shopify Storefront API).
In order to avoid multiple query to the db and upgrade performance, I want to store all datas once a user sees a page:
1- first loading (by page): the method getStaticProps fetch the necessary datas and put everything in a context ShopContext
2- when the user hits the page another time: instead of getStaticProps re-fetch the datas, just use the data in the context.
Is it something logical to do that? And if yes, is it possible to avoid data fetching when a loading page occurs?
Many thanks for your responses ! :)

getServerSideProps vs fetching directly in React

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.

Resources