Part 21: Automating Blog Post Paths in Next.js
[Pages] Loading Data

In this post, we'll explore how to automate the generation of static paths for blog posts in a Next.js application. Instead of manually specifying each post's path, we'll dynamically generate paths by reading Markdown files from a directory. This approach not only saves time but also makes the application more scalable and maintainable.
Problem with Manual Paths
Previously, we used Next.js's getStaticPaths function to define which blog post paths should be statically generated. However, manually listing each post slug can become cumbersome as the number of posts grows.
Here's an example of the manual approach:
// pages/posts/[slug].js
export async function getStaticPaths() {
return {
paths: [
{ params: { slug: 'first-post' } },
{ params: { slug: 'second-post' } },
],
fallback: false,
};
}As you add more posts, you need to update this list, which is not ideal. Let's automate this process!
Reading Markdown Files
We can leverage Node.js's file system capabilities to read the contents of the content/posts directory and automatically generate slugs.
Creating the getSlugs Function
getSlugs FunctionFirst, let's create a function that reads the file names in the content/posts directory and extracts the slugs from these file names:
// lib/posts.js
import { readdir, readFile } from 'fs/promises';
import matter from 'gray-matter';
import { marked } from 'marked';
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));
}How It Works
Read Directory: We use Node.js's
readdirfunction to get a list of files in thecontent/postsdirectory.Filter Markdown Files: We filter the list to include only files ending with
.md.Extract Slugs: We map over the filtered list to remove the
.mdextension, resulting in an array of slugs.
Using getSlugs in getStaticPaths
getSlugs in getStaticPathsNow, let's update getStaticPaths to use our new getSlugs function, so we no longer need to manually specify paths:
// pages/posts/[slug].js
import Head from 'next/head';
import { getPost, getSlugs } from '../../lib/posts';
export async function getStaticPaths() {
const slugs = await getSlugs();
return {
paths: slugs.map((slug) => ({
params: { slug },
})),
fallback: false,
};
}What Changed?
Dynamic Path Generation: We call
getSlugsto retrieve all available slugs and transform them into the appropriate structure forpaths.No Manual Update Needed: Now, adding a new Markdown file automatically makes it available as a post page without any changes to the code.
Testing the Setup
Let's test this by adding a new post:
// content/posts/third-post.md
---
date: "2021-04-23"
title: "Third Post"
---
This is my third post, written in Markdown.With the new file in place, you should be able to visit /posts/third-post and see the content rendered correctly. The getStaticPaths function automatically picked up the new file, and no additional code changes were required.
Conclusion
By automating the generation of static paths using file system operations, we've made our blog application more robust and easier to maintain. This approach eliminates the need for manual updates and allows the app to scale effortlessly as new content is added. As you continue developing your Next.js, consider how automation can streamline your workflows and improve maintainability.
Last updated