hafuture
Back to Blog

Building a Tech Blog with Next.js and MDX

How to build a tech blog using Next.js 16 App Router and MDX.

nextjsmdxweb-development

Building a Tech Blog with Next.js and MDX

In this post, we will explore how to build a tech blog using Next.js 16 and MDX.

Tech Stack

  • Next.js 16: App Router based
  • MDX: Markdown + JSX
  • gray-matter: Frontmatter parsing
  • next-mdx-remote: Server-side MDX rendering

Project Structure

hafuture-app/
├── content/posts/       # MDX posts
│   ├── hello-world.mdx
│   └── vibe-coding-blog.mdx
├── src/
│   ├── app/[locale]/
│   │   └── blog/
│   │       ├── page.tsx           # Blog list
│   │       └── [slug]/page.tsx    # Individual post
│   ├── components/mdx/
│   │   └── mdx-content.tsx       # MDX renderer
│   └── lib/
│       └── posts.ts             # Post data loader

Loading Post Data

We use gray-matter to separate frontmatter and content:

import matter from "gray-matter";

const { data, content } = matter(fileContents);

// data: frontmatter (title, date, tags, etc.)
// content: Markdown body

MDX Rendering

We use next-mdx-remote to render MDX on the server side:

import { MDXRemote } from "next-mdx-remote/rsc";

<MDXRemote
  source={content}
  options={{
    mdxOptions: {
      rehypePlugins: [
        rehypeHighlight,   // Code highlighting
        rehypeSlug,       // Heading slugs
        rehypeAutolinkHeadings, // Heading links
      ],
    },
  }}
/>

SEO Optimization

We use Next.js's Metadata API to set metadata for each post:

export async function generateMetadata({ params }) {
  const { slug } = await params;
  const post = await getPostBySlug(slug);

  return {
    title: post.title,
    description: post.description,
  };
}

Conclusion

Combining Next.js and MDX allows you to build a simple yet powerful Git-based blog system without a CMS. This enables a developer-friendly and easy-to-maintain blog.

In the next post, we will talk about features to add to the blog. Stay tuned!