Next.js is a powerful framework for building static and server-rendered applications with React. In this guide, we will create a simple blog template using Next.js. This includes setting up the project, creating pages and components, and adding Markdown support for writing posts.

Prerequisites

Before we start, ensure you have the following installed:

  • Node.js
  • npm or yarn

Steps for Creating a Blog with Next.js

Step 1: Setting Up the Next.js Project

First, create a new Next.js project:

npx create-next-app my-nextjs-blog
# or
yarn create next-app my-nextjs-blog

Navigate to your project directory:

cd my-nextjs-blog

Step 2: Installing Dependencies

We need to install some additional dependencies to manage Markdown and styles:

npm install gray-matter remark remark-html
# or
yarn add gray-matter remark remark-html

Step 3: Creating the Blog Structure

Create a posts directory in the root of your project to store your Markdown files:

mkdir posts

Add a sample Markdown file, hello-world.md, in the posts directory:

---
title: 'Hello World'
date: '2024-06-08'
---

This is my first blog post using Next.js!

Step 4: Fetching Blog Posts

Create a utility function to fetch and parse the blog posts. Create a file lib/posts.js:

// 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) => {
    return new Date(b.date) - new Date(a.date);
  });
}

Step 5: Creating the Blog Index Page

Create an index page to list all the blog posts. Modify pages/index.js:

// pages/index.js
import { getSortedPostsData } from '../lib/posts';

export async function getStaticProps() {
  const allPostsData = getSortedPostsData();
  return {
    props: {
      allPostsData,
    },
  };
}

export default function Home({ allPostsData }) {
  return (
    <div>
      <h1>My Blog</h1>
      <ul>
        {allPostsData.map(({ id, title, date }) => (
          <li key={id}>
            <a href={`/posts/${id}`}>{title}</a>
            <br />
            <small>{date}</small>
          </li>
        ))}
      </ul>
    </div>
  );
}

Step 6: Creating the Post Page

Create a dynamic route for individual blog posts. Create a file pages/posts/[id].js:

// pages/posts/[id].js
import { useRouter } from 'next/router';
import { getAllPostIds, getPostData } from '../../lib/posts';
import Head from 'next/head';
import ReactMarkdown from 'react-markdown';

export async function getStaticProps({ params }) {
  const postData = await getPostData(params.id);
  return {
    props: {
      postData,
    },
  };
}

export async function getStaticPaths() {
  const paths = getAllPostIds();
  return {
    paths,
    fallback: false,
  };
}

export default function Post({ postData }) {
  return (
    <div>
      <Head>
        <title>{postData.title}</title>
      </Head>
      <article>
        <h1>{postData.title}</h1>
        <div>{postData.date}</div>
        <ReactMarkdown>{postData.content}</ReactMarkdown>
      </article>
    </div>
  );
}

Step 7: Fetching Post Data

Update lib/posts.js to include functions for fetching individual post data and generating paths:

// lib/posts.js
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { remark } from 'remark';
import html from 'remark-html';

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) => {
    return new Date(b.date) - new Date(a.date);
  });
}

export function getAllPostIds() {
  const fileNames = fs.readdirSync(postsDirectory);
  return fileNames.map(fileName => {
    return {
      params: {
        id: fileName.replace(/\.md$/, ''),
      },
    };
  });
}

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(html)
    .process(matterResult.content);
  const contentHtml = processedContent.toString();

  return {
    id,
    content: contentHtml,
    ...matterResult.data,
  };
}

Conclusion

In this guide, we created a basic blog template using Next.js. We set up the project, created a structure for our blog posts, and added support for Markdown. This setup provides a strong foundation for building and customizing your own blog with Next.js.

For more updates on programming trends and tutorials, visit blogsea.net regularly.

Creating a Blog with Next.js – FAQs

Why use Markdown for blog posts? 

Markdown is easy to write and read, making it ideal for content creation.

How do I create a new Next.js project?

Use npx create-next-app my-nextjs-blog or yarn create next-app my-nextjs-blog.

How do I generate static paths for blog posts?

Implement the getStaticPaths function to generate paths for each post.

How do I fetch data for individual blog posts?

Use the getPostData function to read and parse Markdown files for each post.

Can I customize the blog layout?

Yes, you can customize the layout by modifying the pages and component files.

Is it possible to add syntax highlighting for code blocks in posts? 

Yes, you can use plugins like remark-prism to add syntax highlighting to code blocks in Markdown.

Newsletter

I am a Software developer

My name is muhammad adnan and i am a professtional software developer. specialize in designing and developing efficient software applications.

Check out My Portfolio