Part 22: Automatically Generating Blog Post Links on the Home Page in Next.js
[Pages] Loading Data

Building a blog with dynamic content is always a rewarding challenge. Previously, we automated the generation of static paths for individual blog posts using Markdown. However, our Home page still had a manually curated list of posts. In this post, we'll explore how to dynamically generate a list of blog post links on the Home page, using Next.js's powerful features.
The Manual Problem
Initially, our Home page was hardcoded to display a link to a single post:
// pages/index.js
function HomePage() {
return (
<>
<Head>
<title>My Blog</title>
</Head>
<main>
<h1>My Blog</h1>
<ul>
<li>
<Link href="/posts/first-post">
First Post
</Link>
</li>
</ul>
</main>
</>
);
}This approach requires manual updates each time a new post is added. Instead, let's use our existing getSlugs function to automate this process.
Leveraging getStaticProps
getStaticPropsTo pass dynamic data to our Home page, we can use the getStaticProps function. This function runs at build time and allows us to fetch data that can be passed to the page component as props.
Implementing getStaticProps
getStaticPropsWe'll start by modifying our Home page to use getStaticProps and call a new function getPosts that returns both the slug and title for each post:
// pages/index.js
import Head from 'next/head';
import Link from 'next/link';
import { getPosts } from '../lib/posts';
// Fetch posts at build time
export async function getStaticProps() {
const posts = await getPosts();
return {
props: { posts },
};
}
// Render the Home page with dynamic post links
function HomePage({ posts }) {
console.log('[HomePage] render:', posts);
return (
<>
<Head>
<title>My Blog</title>
</Head>
<main>
<h1>My Blog</h1>
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link href={`/posts/${post.slug}`}>
{post.title}
</Link>
</li>
))}
</ul>
</main>
</>
);
}
export default HomePage;Creating the getPosts Function
getPosts FunctionWe need a function that retrieves both the slug and title for each post. We'll create getPosts in our lib/posts.js file:
// lib/posts.js
import { readdir, readFile } from 'fs/promises';
import matter from 'gray-matter';
import { marked } from 'marked';
export async function getPosts() {
const slugs = await getSlugs();
const posts = [];
for (const slug of slugs) {
const post = await getPost(slug);
posts.push({ slug, ...post });
}
return posts;
}
export async function getSlugs() {
const suffix = '.md';
const files = await readdir(`content/posts`);
return files.filter((file) => file.endsWith(suffix))
.map((file) => file.slice(0, -suffix.length));
}Explanation
getSlugs: Retrieves all Markdown file names and extracts slugs.
getPosts: Calls
getSlugsto get all slugs and iterates over them. For each slug, it callsgetPostto get the post's content and metadata, then constructs a post object that includes the slug.
Dynamic Home Page Links
With our setup complete, the Home page now dynamically generates a list of links based on the available posts:
Dynamic Props:
getStaticPropsfetches post data at build time.Dynamic Rendering: The Home page uses these props to render links for each post, displaying the title and linking to the appropriate path.
Testing the Setup
To ensure everything works, you can add more Markdown files in the content/posts directory:
// content/posts/third-post.md
---
date: "2021-04-23"
title: "Third Post"
---
This is my third post, written in Markdown.After rebuilding your application, the Home page should automatically display links to all available posts, including the new ones.
Conclusion
By automating the generation of post links on the Home page, we’ve streamlined the process of adding new content to our blog. This approach not only enhances scalability but also reduces the potential for errors associated with manual updates. Next.js provides powerful tools like getStaticProps, which, when combined with file system operations, enable us to build dynamic and efficient web applications. Happy coding!
Last updated