Building a blog with Next.js and Markdown allows you to create a fast, SEO-friendly site with a simple content management system. In this guide, we’ll walk you through setting up a Next.js project, integrating Markdown for content, and creating a blog website with dynamic routes and posts. By the end, you’ll have a fully functional blog that showcases Markdown posts.
1. Setting Up Your Next.js Project
1.1. Create a New Next.js Project
Start by setting up a new Next.js project using create-next-app
.
npx create-next-app@latest my-blog
cd my-blog
1.2. Install Dependencies
You’ll need gray-matter
to parse front matter in Markdown files and remark
for processing Markdown.
npm install gray-matter remark remark-html
2. Adding Markdown Support
2.1. Create a Directory for Markdown Files
Create a folder named posts
in the root directory of your project. This folder will contain your Markdown files.
mkdir posts
2.2. Add Sample Markdown Files
Create a sample Markdown file in the posts
directory:
// posts/first-post.md
---
title: "My First Post"
date: "2024-09-01"
---
This is the content of my first post. Markdown allows you to **format** text, add [links](https://example.com), and more.
3. Parsing Markdown Files
3.1. Create a Utility Function to Load Posts
Create a lib
directory and add a posts.js
file to handle loading and parsing Markdown files.
// lib/posts.js
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
const postsDirectory = path.join(process.cwd(), 'posts');
export function getSortedPostsData() {
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map(fileName => {
const id = fileName.replace(/\.md$/, '');
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const matterResult = matter(fileContents);
return {
id,
...matterResult.data,
};
});
return allPostsData.sort((a, b) => (a.date < b.date ? 1 : -1));
}
export function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const matterResult = matter(fileContents);
return {
id,
...matterResult.data,
content: matterResult.content,
};
}
4. Building Pages and Components
4.1. Create the Home Page
Edit pages/index.js
to display a list of blog posts.
// pages/index.js
import Link from 'next/link';
import { getSortedPostsData } from '../lib/posts';
export default function Home({ allPostsData }) {
return (
<div>
<h1>My Blog</h1>
<ul>
{allPostsData.map(({ id, title, date }) => (
<li key={id}>
<Link href={`/posts/${id}`}>
<a>{title}</a>
</Link>
<br />
<small>{date}</small>
</li>
))}
</ul>
</div>
);
}
export async function getStaticProps() {
const allPostsData = getSortedPostsData();
return {
props: {
allPostsData,
},
};
}
4.2. Create Dynamic Post Pages
Add a [id].js
file in the pages/posts
directory for dynamic routes.
// pages/posts/[id].js
import { getAllPostIds, getPostData } from '../../lib/posts';
export default function Post({ postData }) {
return (
<div>
<h1>{postData.title}</h1>
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
</div>
);
}
export async function getStaticPaths() {
const paths = getAllPostIds();
return {
paths,
fallback: false,
};
}
export async function getStaticProps({ params }) {
const postData = getPostData(params.id);
return {
props: {
postData,
},
};
}
4.3. Process Markdown Content
Modify lib/posts.js
to include Markdown processing.
import remark from 'remark';
import remarkHtml from 'remark-html';
export async function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const matterResult = matter(fileContents);
const processedContent = await remark().use(remarkHtml).process(matterResult.content);
const contentHtml = processedContent.toString();
return {
id,
contentHtml,
...matterResult.data,
};
}
5. Styling Your Blog
5.1. Add Global Styles
Create a styles/globals.css
file to include global styles.
/* styles/globals.css */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
}
a {
color: #0070f3;
}
a:hover {
text-decoration: underline;
}
Import this CSS file in _app.js
.
// pages/_app.js
import '../styles/globals.css';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
6. Conclusion
In this guide, you learned how to build a simple blog with Next.js and Markdown. You set up a Next.js project, integrated Markdown for content, and created dynamic routes for blog posts. You also learned how to style your blog and process Markdown content for display.
Learn How to Build an Interactive Map with React and Leaflet
Understanding Typing in Programming: Implicit, Explicit, Nominal, Structural, and Duck Typing
About Muhaymin Bin Mehmood
Front-end Developer skilled in the MERN stack, experienced in web and mobile development. Proficient in React.js, Node.js, and Express.js, with a focus on client interactions, sales support, and high-performance applications.