Caching in web development, including Next.js, is a technique to store resources for future requests to improve performance. By caching data, you reduce load times, decrease server workload, and enhance user experience.
A Story-Based Example: The Recipe Blog
Let’s imagine a chef named Alex who runs a popular recipe blog. Her readers often revisit the blog to check their favorite recipes, causing repetitive and unnecessary fetches from the server. To improve her blog’s performance, Alex decides to implement caching in her Next.js 14 application.
Act 1: Implementing ISR (Incremental Static Regeneration)
Alex discovers that Next.js 14 offers a feature called ISR. With ISR, when a user first visits a page, Next.js generates the static page and caches it. Subsequent visitors receive the cached page, and after a defined interval, the page is regenerated in the background, keeping the content fresh.
Step 1: Set Up Your Project
Create a Next.js project if you haven’t already, and navigate to it:
npx create-next-app@latest my-blog
cd my-blog
BashStep 2: Create a Blog Page
In the app/blog/page.tsx
, fetch and list all posts using ISR for caching.
// app/blog/page.tsx
import { getStaticProps } from 'next';
import Link from 'next/link';
const demoAPI = 'https://public-api.wordpress.com/wp/v2/sites/demo.wp-api.org/posts';
export const getStaticProps = async () => {
const res = await fetch(demoAPI);
const posts = await res.json();
return {
props: { posts },
revalidate: 10, // seconds
};
};
const BlogPage = ({ posts }) => {
return (
<div>
<h1>Blog</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${post.slug}`}>
<a>{post.title.rendered}</a>
</Link>
</li>
))}
</ul>
</div>
);
};
export default BlogPage;
JavaScriptStep 3: Create Dynamic Blog Post Pages
Create dynamic post pages at app/blog/[slug]/page.tsx
using ISR.
// app/blog/[slug]/page.tsx
import { getStaticPaths, getStaticProps } from 'next';
export const getStaticPaths = async () => {
const res = await fetch(demoAPI);
const posts = await res.json();
const paths = posts.map((post) => ({
params: { slug: post.slug },
}));
return {
paths,
fallback: 'blocking',
};
};
export const getStaticProps = async ({ params }) => {
const res = await fetch(`${demoAPI}?slug=${params.slug}`);
const postArray = await res.json();
const post = postArray.length > 0 ? postArray[0] : null;
if (!post) {
return {
notFound: true,
};
}
return {
props: { post },
revalidate: 10, // seconds
};
};
const PostPage = ({ post }) => {
if (!post) return <p>Post not found</p>;
return (
<article>
<h1>{post.title.rendered}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content.rendered }} />
</article>
);
};
export default PostPage;
JavaScriptStep 4: Run the Development Server
npm run dev
JavaScriptAnd visit http://localhost:3000/blog
to see your blog posts.
Notes:
- The
revalidate
property ingetStaticProps
andgetStaticPaths
determines how often Next.js will regenerate the page upon a request after it’s been built. - The paths returned by
getStaticPaths
will be statically generated at build time. - The
fallback: 'blocking'
ingetStaticPaths
means that new paths not returned bygetStaticPaths
will wait for the HTML to be generated before being served to users. - In a real-world scenario, you would replace the
demoAPI
URL with the actual endpoint of your WordPress blog API.