Building a blog with Next.js and Markdown

Building a blog with Next.js and Markdown is a great way to create a simple, fast and easy-to-maintain blog. Markdown is a lightweight markup language that allows you to write text in a simple format that can be converted to HTML. In this tutorial, we will walk you through the process of building a blog with Next.js and Markdown.

Step 1: Create a new project

To get started, you will need to create a new Next.js project. You can do this by running the following command in your terminal:

npx create-next-app my-blog

This command will create a new directory called “my-blog” that contains the basic structure of a Next.js application.

 

Step 2: Install dependencies

We will be using the gray-matter and remark packages to parse the markdown files and extract the frontmatter. Run the following command to install the dependencies

npm install gray-matter remark

 

Step 3: Create a data directory

Create a directory called data in the root of your project. This directory will contain all the markdown files that will be used to create the blog posts. Each markdown file should contain the post’s content and frontmatter, which will be used to extract metadata like the post’s title, date, and tags.

To create a data directory in the root of your project, you can use the following command:

mkdir data

This command will create a new directory called “data” in the root of your project. You can then add markdown files to this directory that will be used to create the blog posts.

Alternatively, you can create the directory manually by navigating to the root of your project in your file explorer and creating a new folder named “data”.

Once you have created the directory, you can add markdown files to it. Here is an example of a markdown file that contains the post’s content and frontmatter:

---
title: "Hello World"
date: "2022-01-01"
tags: ["javascript", "web development"]
---

# Hello World

This is my first blog post in my new blog built with Next.js and Markdown.

In this example, the frontmatter contains metadata such as the title, date and tags, which will be used to extract the metadata of the blog post.

 

Step 4: Fetch data

Next.js provides a built-in method called getStaticProps which allows you to fetch data on the server before the component is rendered. This method is called on the server before the component is rendered, so it can be used to fetch data from the data directory. We will use this method to fetch all the markdown files and parse them using gray-matter and remark. The data from the frontmatter will be used to create the metadata for the blog post, and the content will be passed to the component as props, so it can be rendered on the server.

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

export async function getStaticProps() {
  const files = fs.readdirSync("data");
  const posts = files.map((file) => {
    const markdownWithMetadata = fs
      .readFileSync(path.join("data", file))
      .toString();
    const { data, content } = matter(markdownWithMetadata);
    const processedContent = await remark()
      .use(html)
      .process(content);
    return { ...data, content: processedContent.toString() };
  });
  return { props: { posts } };
}

 

Step 5: Create a template

Create a template for your blog posts in the pages directory. This template will be used to render each blog post on the server. You can use the data from the frontmatter and the parsed markdown content passed to the component as props to create the layout for the blog post.

To create a template for your blog posts, you can create a new React component in the pages directory. This component will be used to render each blog post on the server. Here is an example of a template component that you can use:

import { useRouter } from 'next/router'

const PostTemplate = ({ post }) => {
  const router = useRouter();
  if (!router.isFallback && !post?.slug) {
    return <ErrorPage statusCode={404} />
  }
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.date}</p>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </div>
  )
}

export default PostTemplate

In this example, we are importing the useRouter hook from next/router to access the router object and check the current route. The component accepts post as a prop, which is passed from getStaticProps method, and we are using this prop to render the title, date and content of the blog post.

You can then use this template component in your [slug].js page to render the post.

import { getStaticProps } from './[slug].js'
import PostTemplate from '../components/PostTemplate'

export default function Post({ post }) {
  return <PostTemplate post={post} />
}

export { getStaticProps }

This way, you can create a reusable template for all your blog posts, that can be easily customized and styled to match your website’s design.

 

Step 6: Create the blog index

Create an index page for your blog in the pages directory. This page will list all the blog posts and will be the main entry point to your blog. You can use the data from the getStaticProps method to render a list of all the blog posts.

 

Step 7: Build and Deploy

When you’re ready to deploy your application, you can use the following command to build your application:

npm run build

After the build process is complete, you can start the application by running:

npm run start

Your application will be available at http://localhost:3000.

By building a blog with Next.js and Markdown, you get a simple, fast and easy to maintain blog. Markdown allows you to write content in a simple, readable format, while Next.js provides a powerful framework for building server-side rendered applications.

In addition, using a static directory for storing markdown files allows you to easily add, edit and update your blog posts without the need for a database or CMS. This makes it easy to collaborate with others or work on your blog from different devices.

Here is an example of how the final index.js file in the pages directory would look like:

import Link from "next/link";

export default function Blog({ posts }) {
  return (
    <div>
      {posts.map((post) => (
        <div key={post.slug}>
          <h2>
            <Link href={`/post/${post.slug}`}>
              <a>{post.title}</a>
            </Link>
          </h2>
          <p>{post.excerpt}</p>
        </div>
      ))}
    </div>
  );
}

export async function getStaticProps() {
  // code to fetch and parse markdown files
}

By following this tutorial, you should have a basic understanding of how to build a blog with Next.js and Markdown. You can now start creating your own blog and take advantage of the features that Next.js and Markdown have to offer.

In addition to the basic setup, there are many other features and functionalities that you can add to your blog. Some examples include:

  • Pagination: Next.js has built-in support for pagination which makes it easy to split your blog posts into multiple pages.
  • Search: you can use a search engine like Algolia or Elasticsearch to enable searching through your blog posts.
  • Comments: you can use a commenting service like Disqus or Utterances to enable commenting on your blog posts.
  • Analytics: you can use a service like Google Analytics or Fathom to track the traffic on your blog.
  • SEO: you can optimize your blog for search engines by adding meta tags and structured data to your pages.

In conclusion, building a blog with Next.js and Markdown is a great way to create a simple, fast, and easy to maintain blog that can be easily updated and deployed. By using Next.js, you have access to a wide range of features and tools that can help you create a high-performance blog that can be easily optimized for SEO and analytics. Markdown allows you to write content in a simple, readable format that can be easily converted to HTML. Furthermore, storing the blog posts in markdown files makes it easy to collaborate with others and work on your blog from different devices.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top