Create Markdown-based Next.js Blog

April 12, 2024

9 min read

Creating a blog using Next.js, React, and MDX allows you to combine Markdown's simplicity with React's power, offering a versatile platform for writing and deploying content. MDX is an extension of Markdown that enables you to use JSX (JavaScript XML) directly in your Markdown files. This tutorial will guide you through setting up a simple markdown-based blog using these technologies.

Prerequisites

  • Basic knowledge of JavaScript and React.
  • Node.js and npm installed on your computer.

Step 1: Set Up Your Next.js Project

  1. Create a new Next.js app: Open your terminal and run the following command to create a new Next.js app:

    npx create-next-app my-mdx-blog

    Replace my-mdx-blog with whatever you want to name your project.

  2. Navigate into your project directory:

    cd my-mdx-blog

Step 2: Install Dependencies

You need to add MDX support to your project along with a few utilities to handle Markdown files.

  1. Install @next/mdx and gray-matter: @next/mdx allows you to use MDX in your Next.js app, and gray-matter is used to parse metadata within Markdown files.

    npm install @next/mdx @mdx-js/loader gray-matter
  2. Update next.config.js: Modify the next.config.js file to add MDX support:

    const withMDX = require('@next/mdx')({
      extension: /\.mdx?$/
    });
    module.exports = withMDX({
      pageExtensions: ['js', 'jsx', 'md', 'mdx']
    });

Step 3: Set Up MDX Pages

  1. Create a pages directory: Your Next.js app already has a pages directory. You will store your MDX files here.

  2. Add an MDX file: Create a new file inside the pages directory. For example, about.mdx:

    # About
    This is an MDX-based blog post. You can use React components here.
    
    <button onClick={()=> alert('Hello!')}>Click Me</button>

Step 4: Parsing Front Matter

gray-matter is used to parse front matter from MDX files, which allows you to add metadata like title, date, and author.

  1. Modify the MDX loading: You need to modify how MDX files are loaded to include front matter parsing. Update your MDX files' import method by creating a higher-order component that uses gray-matter.

    Create a new file called lib/mdx.js and add:

    import fs from 'fs';
    import path from 'path';
    import matter from 'gray-matter';
    
    export function getPost(slug) {
      const filePath = path.join(process.cwd(), 'pages', `${slug}.mdx`);
      const fileContents = fs.readFileSync(filePath, 'utf8');
      const { data, content } = matter(fileContents);
      return { data, content };
    }

Step 5: Display MDX Content

  1. Modify a page to use MDX content: You can modify the index.js page to load an MDX file and render it.
    import React from 'react';
    import { getPost } from '../lib/mdx';
    import { MDXRemote } from 'next-mdx-remote';
    
    export default function Home({ content }) {
      return <MDXRemote {...content} />;
    }
    
    export async function getStaticProps() {
      const post = getPost('about');
      return { props: { content: post.content } };
    }

Step 6: Start Your Development Server

Run your development server to see your blog in action:

npm run dev

Navigate to http://localhost:3000 in your browser to see your new MDX blog.

Putting it all together

With this setup, you can create blog posts as MDX files that mix Markdown with React components. This flexibility lets you add interactive or dynamic content within your static blog posts, making it a powerful combination for web developers.