I want to display the latest video from a YouTube channel on a website. The channel uploads at maximum once per day, so I'm caching the response of my API route for 1 day (86400 seconds) in my vercel.json
like so:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "access-control-allow-origin",
"value": "*"
},
{
"key": "Cache-Control",
"value": "s-maxage=86400"
}
]
}
]
}
I want to use getStaticProps
with incremental static regeneration so that my API route only gets sent requests at most once per day, but I'm not sure how to write the request to my API route.
The Next.js docs say:
Note: You should not use
fetch()
to call an API route ingetStaticProps
. Instead, directly import the logic used inside your API route. You may need to slightly refactor your code for this approach.Fetching from an external API is fine!
What does this mean? Is my current method of writing my request wrong?
// /pages/index.js
import Header from '../components/header/header'
import MainContent from '../components/main-content/main-content'
import Footer from '../components/footer/footer'
export default function Index({ videoTitle, videoURL, videoThumbnailData }) {
return (
<>
<Header />
<MainContent
videoTitle={videoTitle}
videoURL={videoURL}
videoThumbnailData={videoThumbnailData}
/>
<Footer />
</>
)
}
// Called at build time, and response revalidated after 1 day (86400 seconds)
// since internal API response is cached on Vercel Edge network for 1 day (see /pages/api/get-latest-video.js)
export async function getStaticProps() {
// Fetch YouTube videos from internal API route /pages/api/get-latest-video.js
const res = await fetch(`${process.env.API_ROUTES_URL}/api/get-latest-video`)
const data = await res.json()
// Returned as props to page
return {
props: {
videoTitle: data.videoTitle,
videoURL: data.videoURL,
videoThumbnailData: data.videoThumbnailData
},
revalidate: 86400
}
}
// /components/main-content/main-content.js
import Section from './section'
import Image from 'next/image'
export default function MainContent({ videoTitle, videoURL, videoThumbnailData }) {
return (
<main>
<Section>
<a href={videoURL}>
{videoTitle}
</a>
<Image
src={videoThumbnailData.url}
width={videoThumbnailData.width}
height={videoThumbnailData.height}
/>
</Section>
</main>
)
}
Your request /api/get-latest-video
is supposed to be send from the browser to the server, then the server probably has some kind of a route handler like:
routeMatches('/api/get-latest-video', ( req, res )=>{
requestDB('latestVideos').then( latestVideos => {
respondWithLatestVideos( req, res, latestVideos );
})
});
Now, getStaticProps
runs on the server side. So you can request your DB directly inside getStaticProps
, instead of sending a request to the server which requests the DB.
export async function getStaticProps() {
// Fetch YouTube videos from internal API route /pages/api/get-latest-video.js
// const res = await fetch(`${process.env.API_ROUTES_URL}/api/get-latest-video`)
// const data = await res.json()
const data = await requestDB('latestVideos')
...
}
There is a slightly more informative note "write server side code directly" further down on the same NextJs docs page:
Note that
getStaticProps
runs only on the server-side. It will never be run on the client-side. It won’t even be included in the JS bundle for the browser. That means you can write code such as direct database queries without them being sent to browsers. You should not fetch an API route fromgetStaticProps
— instead, you can write the server-side code directly ingetStaticProps
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With