Introduction to Building a Blog with Next.js

Creating a blog is a common use case for web development, and Next.js is a fantastic framework for building one. With features like server-side rendering (SSR), static site generation (SSG), and dynamic routing, you can create a high-performance and SEO-friendly blog. In this step-by-step guide, we'll walk through the process of creating a blog using Next.js.


Step 1: Setting Up Your Next.js Project

1. Start by creating a new Next.js project. If you haven't already installed Next.js, you can do so with:


npx create-next-app my-blog

2. Navigate to the project directory:


cd my-blog

Your Next.js project is now set up and ready to build your blog.


Step 2: Creating Blog Posts

1. Inside your project directory, create a new folder called "posts" to store your blog posts:


mkdir posts

2. Create your first blog post in the "posts" folder. For example, create a file named "my-first-post.md" for a Markdown post:


---
title: My First Blog Post
date: 2023-10-27
---
# Welcome to My Blog
This is my first blog post using Next.js. It's an exciting journey!

You can create more blog posts in a similar format. The frontmatter contains metadata like the post title and date.


Step 3: Creating the Blog Page

1. Create a new file named "blog.js" in the "pages" directory to render your blog posts:


// pages/blog.js
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import Link from 'next/link';
export default function Blog({ posts }) {
return (
<div>
<h2>Welcome to My Blog</h2>
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link href={`/blog/${post.slug}`}>
<a>{post.frontmatter.title}</a>
</Link>
</li>
))}
</ul>
</div>
);
}
export async function getStaticProps() {
const postsDirectory = path.join(process.cwd(), 'posts');
const fileNames = fs.readdirSync(postsDirectory);
const posts = fileNames.map((fileName) => {
const filePath = path.join(postsDirectory, fileName);
const fileContent = fs.readFileSync(filePath, 'utf-8');
const { data, content } = matter(fileContent);
return {
frontmatter: data,
slug: fileName.replace(/\.md$/, ''),
};
});
return {
props: {
posts,
},
};
}

The code above reads the Markdown files in the "posts" directory, extracts metadata from frontmatter, and renders a list of blog posts.

2. Create a new file named "[slug].js" in the "pages/blog" directory to render individual blog posts:


// pages/blog/[slug].js
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import marked from 'marked';
export default function BlogPost({ frontmatter, content }) {
return (
<div>
<h1>{frontmatter.title}</h1>
<p>Date: {frontmatter.date}</p>
<div dangerouslySetInnerHTML={{ __html: marked(content) }} />
</div>
);
}
export async function getStaticPaths() {
const postsDirectory = path.join(process.cwd(), 'posts');
const fileNames = fs.readdirSync(postsDirectory);
const paths = fileNames.map((fileName) => ({
params: { slug: fileName.replace(/\.md$/, '') },
}));
return {
paths,
fallback: false,
};
}
export async function getStaticProps({ params }) {
const { slug } = params;
const postsDirectory = path.join(process.cwd(), 'posts');
const filePath = path.join(postsDirectory, `${slug}.md`);
const fileContent = fs.readFileSync(filePath, 'utf-8');
const { data, content } = matter(fileContent);
return {
props: {
frontmatter: data,
content,
},
};
}

This code reads individual Markdown files in the "posts" directory, extracts metadata and content, and renders a single blog post.

3. To create a navigation link to your blog page, add the following code to any other page in the "pages" directory:


<Link href="/blog">
<a>Visit My Blog</a>
</Link>

Now you can navigate to your blog page from any other page in your Next.js app.


Step 4: Styling Your Blog

You can add styles to your blog by importing CSS or using CSS-in-JS libraries like styled-components or Emotion. Customizing your blog's appearance is up to your design preferences.