Blog.

Creating a Markdown Blog with Next.js

Cover Image for Creating a Markdown Blog with Next.js
Dan Adams
Dan Adams

In today's digital world, blogging remains a powerful way to share your thoughts, knowledge, and experiences with a global audience. Markdown, with its simplicity and versatility, has become a preferred format for content creation among many writers and developers. Combining Markdown with the popular React framework Next.js allows you to build a high-performance and SEO-friendly Markdown blog. In this article, we'll walk you through the process of creating a Markdown blog with Next.js.

Prerequisites

Before we dive into building our Markdown blog, make sure you have the following prerequisites installed on your system:

  1. Node.js: Download and install Node.js from nodejs.org.

  2. npm or Yarn: npm comes bundled with Node.js, but you can also use Yarn as a package manager. You can install Yarn via npm by running npm install -g yarn.

Step 1: Setting Up a New Next.js Project

We'll start by creating a new Next.js project. Open your terminal and run the following commands:

npx create-next-app markdown-blog
cd markdown-blog

This will create a new Next.js project in a directory named markdown-blog.

To start the development server:

npm run dev

Step 2: Installing Dependencies

In your project directory, install the necessary dependencies for handling Markdown and rendering it using Next.js:

npm install gray-matter remark react-markdown
  • gray-matter will help us parse the metadata from our Markdown files.
  • remark is a powerful Markdown processor.
  • react-markdown allows us to render Markdown content as React components.

Step 3: Creating a Markdown Folder

Create a folder in your project directory to store your Markdown blog posts. You can name it posts. Inside this folder, create a sample Markdown file, e.g., sample.md, with the following content:

---
title: My First Post
date: "2023-09-01"
---

# Welcome to My Blog!

This is the first post on my Markdown blog. We'll be sharing exciting content here. Stay tuned!

The metadata block at the top (between --- lines) is used to specify post details like title and date.

Step 4: Parsing Markdown Files

In your Next.js project, create a JavaScript file, e.g., lib/blog.js, to parse the Markdown files using gray-matter:

import fs from "fs";
import path from "path";
import matter from "gray-matter";

const postsDirectory = path.join(process.cwd(), "posts");

export function getAllPosts() {
  const fileNames = fs.readdirSync(postsDirectory);

  return fileNames.map((fileName) => {
    const slug = fileName.replace(/\.md$/, "");
    const fullPath = path.join(postsDirectory, fileName);
    const fileContents = fs.readFileSync(fullPath, "utf8");
    const { data, content } = matter(fileContents);

    return {
      slug,
      ...data,
      content,
    };
  });
}

Step 5: Creating a Blog Page

Next, create a new page in your Next.js project to display the blog posts. Inside the pages directory, create a folder called blog. Inside the pages/blog directory, create a file named index.js:

import { getAllPosts } from "../lib/blog";
import Link from "next/link";
import { getAllPosts } from "../../lib/blog";

export default function Blog({ posts }) {
  return (
    <div>
      <h1>My Markdown Blog</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>
            <Link href={`/blog/${post.slug}`}>
              <h2>{post.title}</h2>
            </Link>
            <p>{post.date}</p>
          </li>
        ))}
      </ul>
    </div>
  );
}

export async function getStaticProps() {
  const posts = getAllPosts();

  return {
    props: {
      posts,
    },
  };
}

The blog archive page should now list our blog posts at http://localhost:3000/blog.

Step 6: Rendering Markdown Content

To render the Markdown content within your blog post, you'll need to utilize react-markdown. First, install it if you haven't already:

npm install react-markdown

Let's create a function in lib/blog.js to fetch a single post by it's slug:

export function getPostBySlug(slug) {
  const fullPath = path.join(postsDirectory, slug + ".md");
  const fileContents = fs.readFileSync(fullPath, "utf-8");
  const { data, content } = matter(fileContents); // use gray-matter package to convert markdown into a JS

  return {
    ...data,
    content,
  };
}

Now, create the file pages/blog/[slug].js. This is a dynamic route that we can use as a template to create all of our posts. Inside [slug].js, add the following:

import { getAllPosts, getPostBySlug } from "@/lib/blog";
import React from "react";
import ReactMarkdown from "react-markdown";

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

// This runs at build time and fetches the post data from the Post() react component
// `params` argument is received by getStaticPaths()
export async function getStaticProps({ params }) {
  const post = getPostBySlug(params.slug);

  return {
    props: {
      post,
    },
  };
}

// This runs at build time to create all our single post routes, e.g. /blog/sample
export async function getStaticPaths() {
  const posts = getAllPosts();

  return {
    paths: posts.map((post) => {
      return {
        params: {
          slug: post.slug,
        },
      };
    }),
    fallback: false,
  };
}

Our sample post is now available at http://localhost:3001/blog/sample.

Step 7: Styling Your Blog

Style your Markdown blog to make it visually appealing. You can use CSS, a CSS-in-JS solution, or a UI library like Tailwind CSS.

Conclusion

In this tutorial, we've covered the process of creating a Markdown blog with Next.js. You've learned how to set up a Next.js project, parse Markdown files, and render Markdown content using react-markdown. With this foundation, you can now expand your blog by adding more posts and customizing the design to match your preferences. Happy blogging!

,