Why NextWhy Next
목록으로
💻 개발2분 읽기

Next.js로 MDX 블로그 직접 만들기 - 이 블로그를 만든 방법

CMS 없이 마크다운 파일만으로 굴러가는 블로그를 Next.js 16 App Router 로 만든 과정. 폴더 구조, MDX 설정, SEO 까지 실제 코드 흐름으로 정리했습니다.

핵심 요약

글을 src/content/posts 아래 .mdx 파일로 두고, @next/mdx 로 렌더하면 CMS 없이도 블로그가 굴러간다. 파일이 곧 URL, frontmatter 대신 meta export 로 목록과 메타데이터를 만든다.

목차

지금 읽고 계신 이 블로그는 데이터베이스도, 관리자 화면도 없습니다. 글은 전부 마크다운 파일 한 장이에요. 어떻게 만들었는지 그대로 공개합니다.

왜 파일 기반인가

블로그 도구는 많지만, 1인 개발자에게는 대부분 과합니다.

  • CMS: 관리 화면·연동·요금이 따라옵니다
  • 노션 연동: 편하지만 렌더·속도·커스텀에서 막힙니다
  • 마크다운 파일: 글이 코드와 함께 버전 관리되고, 무료이며, git push 가 곧 발행입니다

저는 세 번째를 골랐습니다. 마찰이 가장 적으니까요.

폴더 구조

핵심만 보면 이렇게 생겼습니다.

src/
├── app/
│   ├── page.tsx              # 홈 - 글 목록
│   ├── posts/[slug]/page.tsx # 글 상세
│   └── sitemap.ts            # /sitemap.xml
├── content/posts/*.mdx       # ← 글은 여기에만 추가
└── lib/posts.ts              # 목록·메타 로딩

파일명이 곧 URL 이 됩니다. hello.mdx/posts/hello 로 열려요.

MDX 설정

App Router 에서 MDX 를 쓰려면 @next/mdx 를 붙입니다. Next 16 은 Turbopack 이 기본이라, remark/rehype 플러그인을 문자열 이름으로 넘겨야 합니다(함수 참조는 못 넘깁니다).

const withMDX = createMDX({
  options: {
    remarkPlugins: ["remark-gfm"],   // 표·취소선 지원
    rehypePlugins: ["rehype-slug"],  // 제목 앵커
  },
})

frontmatter 대신 meta export

보통 마크다운 상단의 --- 블록(frontmatter)에 제목·날짜를 적지만, MDX 는 자바스크립트를 품을 수 있어 더 깔끔한 방법이 있습니다. 그냥 객체를 export 하는 거예요.

export const meta = {
  title: "글 제목",
  date: "2026-07-06",
  category: "dev",
}

## 본문 시작

목록 페이지에서는 각 파일을 동적 import 해서 이 meta 만 읽습니다.

const mod = await import(`@/content/posts/${slug}.mdx`)
return mod.meta   // 본문 렌더 없이 메타만

파싱 라이브러리도, 별도 인덱스도 필요 없습니다.

SEO 는 처음부터

블로그의 목적이 유입이라면 SEO 는 나중이 아니라 처음에 넣어야 합니다. 저는 글별 메타데이터·Open Graph·JSON-LD 구조화 데이터에 sitemap.xml·robots.txt·rss.xml 까지 기본으로 깔았어요. 이 이야기는 다음 글에서 더 자세히 다룰게요.

정리

  • 글은 .mdx 파일 한 장, 파일명이 URL
  • @next/mdx + 문자열 플러그인(Turbopack)
  • frontmatter 대신 export const meta
  • SEO 는 첫 커밋부터

이 구조 그대로면 여러분 블로그도 30분이면 띄울 수 있어요. 저는 이 방식으로 오늘의 파도 같은 제품 이야기를 계속 쌓아가고 있어요.

자주 묻는 질문

왜 CMS 대신 MDX 파일을 쓰나요?

글이 코드와 함께 버전 관리되고, 무료이며, 배포가 곧 발행이라 1인 개발자에게 마찰이 가장 적습니다. 이미지·코드·컴포넌트도 자유롭게 넣을 수 있고요.

frontmatter 없이 어떻게 목록을 만드나요?

각 .mdx 상단에서 meta 객체를 export 하고, 목록 페이지에서 파일을 동적 import 해 그 meta 만 읽으면 됩니다. 별도 파싱 라이브러리가 필요 없습니다.

관련 글