리스트로 돌아가기
마크다운에 React 컴포넌트를 넣으면? MDX로 콘텐츠 관리하기 thumbnail

마크다운에 React 컴포넌트를 넣으면? MDX로 콘텐츠 관리하기

Next.js와 MDX를 활용해서 동적이고 인터랙티브한 콘텐츠를 만드는 방법을 알아봤어요. 마크다운의 편리함과 React 컴포넌트의 강력함을 결합한 실전 가이드입니다.

2026-01-01 00:00

마크다운에 React 컴포넌트를 넣으면? MDX로 콘텐츠 관리하기

안녕하세요! 포테코입니다.

최근 웹 개발 트렌드에서 마크다운(Markdown)을 활용한 콘텐츠 관리가 주목받고 있어요. 특히 Next.js와 MDX를 결합하면 마크다운의 간편함과 React 컴포넌트의 강력함을 동시에 활용할 수 있어서, 블로그나 문서 사이트를 구축할 때 정말 유용합니다.

이번 글에서는 Next.js 프로젝트에서 MDX를 설정하고 활용하는 방법을 단계별로 살펴볼게요. 실무에서 바로 적용할 수 있는 예시와 함께 설명하겠습니다.

왜 MDX를 사용할까?

전통적인 마크다운은 정적인 콘텐츠에 적합하지만, 현대적인 웹사이트에서는 인터랙티브한 요소가 필요해요. MDX는 마크다운과 React의 장점을 결합해서 이런 이점들을 제공합니다.

  • 마크다운의 간편함: 기존 마크다운 문법을 그대로 사용할 수 있어서 콘텐츠 작성이 쉬워요
  • React 컴포넌트 통합: 마크다운 안에서 React 컴포넌트를 직접 사용할 수 있어서 동적인 콘텐츠를 만들 수 있습니다
  • 타입 안정성: TypeScript와 함께 사용하면 타입 체크가 가능해서 더 안전한 코드를 작성할 수 있어요
  • 확장성: 커스텀 컴포넌트를 만들어 재사용할 수 있어서 일관된 디자인을 유지할 수 있습니다

실무에서 블로그나 문서 사이트를 만들 때, MDX를 사용하면 콘텐츠 작성과 개발 작업을 효율적으로 분리할 수 있어서 정말 유용해요.

프로젝트 설정

1. 필요한 패키지 설치

pnpm add @next/mdx @mdx-js/loader @mdx-js/react

2. next.config.ts 설정

import type { NextConfig } from "next";
import createMDX from "@next/mdx";
 
const withMDX = createMDX({
  extension: /\.mdx?$/,
  options: {
    remarkPlugins: [],
    rehypePlugins: [],
  },
});
 
const nextConfig: NextConfig = {
  pageExtensions: ["js", "jsx", "ts", "tsx", "md", "mdx"],
};
 
export default withMDX(nextConfig);

이 설정을 통해 .mdx 파일을 Next.js 페이지로 직접 사용할 수 있어요. 프로젝트의 app 디렉토리에 .mdx 파일을 추가하면 자동으로 라우트가 생성됩니다.

기본 사용법

마크다운 파일 생성

posts/example.mdx 파일을 생성하고 다음과 같이 작성할 수 있습니다:

---
title: "제목"
date: "2025-01-10"
---
 
# 안녕하세요
 
이것은 **마크다운** 콘텐츠입니다.

React 컴포넌트 사용

MDX의 가장 큰 강점은 마크다운 안에서 React 컴포넌트를 직접 사용할 수 있다는 점이에요. 이를 통해 정적인 콘텐츠에 동적인 요소를 쉽게 추가할 수 있습니다.

import { Button } from "@/components/ui/button";
 
# 컴포넌트 예제
 
마크다운 안에서도 버튼을 사용할 있습니다:
 
<Button onClick={() => alert('클릭!')}>
  클릭하세요
</Button>

이렇게 활용할 수 있습니다:

MDX 파일에서 사용하는 컴포넌트는 프로젝트의 다른 컴포넌트와 동일하게 스타일링할 수 있습니다. 테마 시스템과 통합하면 더욱 일관된 사용자 경험을 제공할 수 있습니다.

고급 활용법

1. 커스텀 컴포넌트 매핑

MDX에서 사용하는 HTML 태그를 커스텀 컴포넌트로 매핑할 수 있어요.

// mdx-components.tsx
import type { MDXComponents } from "mdx/types";
 
export function useMDXComponents(components: MDXComponents): MDXComponents {
  return {
    h1: ({ children }) => <h1 className="text-4xl font-bold">{children}</h1>,
    p: ({ children }) => <p className="text-lg leading-relaxed">{children}</p>,
    ...components,
  };
}

2. 프론트매터(Frontmatter) 활용

프론트매터는 마크다운 파일의 상단에 위치한 메타데이터 영역이에요. ---로 감싸진 YAML 형식의 데이터로, 각 글의 제목, 설명, 작성일, 썸네일 이미지 등의 정보를 구조화된 형태로 저장할 수 있습니다.

프론트매터가 필요한 이유

프론트매터를 사용하면 여러 이점이 있어요:

  1. 콘텐츠와 메타데이터 분리: 글의 본문 내용과 메타 정보를 명확히 구분해서 관리할 수 있습니다
  2. 일관된 데이터 구조: 모든 글에서 동일한 형식으로 메타데이터를 관리해서 데이터 처리와 검색이 용이해요
  3. SEO 최적화: 제목, 설명, 썸네일 등의 정보를 쉽게 추출해서 메타 태그나 Open Graph 태그에 활용할 수 있습니다
  4. 리스트 페이지 구성: 글 목록을 표시할 때 제목, 설명, 날짜 등을 별도로 파싱할 필요 없이 바로 사용할 수 있어요

각 MDX 파일의 메타데이터를 프론트매터로 관리할 수 있습니다:

import matter from "gray-matter";
import fs from "fs";
 
export function getPost(slug: string) {
  const fileContent = fs.readFileSync(`posts/${slug}.mdx`, "utf-8");
  const { data, content } = matter(fileContent);
 
  return {
    frontmatter: data,
    content,
  };
}

3. 코드 하이라이팅

rehype-highlight 또는 remark-prism과 같은 라이브러리를 사용해서 코드 블록에 문법 하이라이팅을 적용할 수 있어요.

import rehypeHighlight from "rehype-highlight";
 
const withMDX = createMDX({
  options: {
    rehypePlugins: [rehypeHighlight],
  },
});

실제 프로젝트 적용 사례

Poteco Studio에서는 저널 페이지를 MDX로 구현했어요. 실제 프로젝트에서 MDX를 사용하면서 얻은 이점들을 정리해봤습니다:

  • 콘텐츠 관리의 유연성: 개발자가 아닌 팀원도 마크다운 문법만 알면 쉽게 글을 작성할 수 있어요
  • 일관된 디자인: 커스텀 컴포넌트를 통해 모든 글의 스타일을 통일해서 브랜드 일관성을 유지할 수 있습니다
  • SEO 최적화: Next.js의 서버 사이드 렌더링을 활용해서 검색 엔진 최적화가 가능해요
  • 개발 효율성: 콘텐츠와 코드를 분리해서 관리할 수 있어서 유지보수가 쉬워집니다

주의사항 및 베스트 프랙티스

1. 보안 고려사항

MDX 파일에서 사용자 입력을 직접 렌더링하는 경우, XSS 공격을 방지하기 위해 적절한 sanitization이 필요해요.

사용자 입력을 MDX로 렌더링할 때는 반드시 검증과 sanitization을 수행해야 합니다. next-mdx-remote는 기본적으로 안전하지만, 외부 소스의 콘텐츠를 사용할 때는 추가적인 보안 조치가 필요합니다.

2. 성능 최적화

대량의 MDX 파일을 처리할 때는 다음 방법들을 고려해볼 수 있어요:

  • 빌드 타임에 미리 컴파일
  • 동적 임포트를 활용한 코드 스플리팅
  • 캐싱 전략 수립

Next.js의 getStaticPropsgetStaticPaths를 활용하면 빌드 타임에 모든 MDX 파일을 미리 컴파일할 수 있어 런타임 성능이 향상됩니다.

3. 타입 안정성

TypeScript를 사용하는 경우, 프론트매터의 타입을 정의하는 것이 좋아요:

interface PostFrontmatter {
  title: string;
  description: string;
  date: string;
  thumbnail?: string;
}

Zod 스키마를 사용하면 프론트매터의 타입을 런타임에서도 검증할 수 있어 더욱 안전합니다. 현재 프로젝트에서는 PostMetaSchema를 사용하여 프론트매터를 검증하고 있습니다.

마무리

MDX는 마크다운의 편리함과 React의 강력함을 결합한 정말 훌륭한 도구예요. Next.js와 함께 사용하면 콘텐츠 중심의 웹사이트를 효율적으로 구축할 수 있습니다.

이번 글에서 아래와 같은 내용을 다뤄봤어요.

  • MDX의 기본 설정 방법
  • React 컴포넌트를 마크다운에서 사용하는 방법
  • 프론트매터를 활용한 메타데이터 관리
  • 보안과 성능을 고려한 베스트 프랙티스

MDX를 활용하면 개발자뿐만 아니라 콘텐츠 작성자도 쉽게 글을 작성할 수 있어서, 팀 전체의 생산성을 높일 수 있어요.
앞으로도 MDX를 활용한 다양한 실전 사례와 팁을 공유할 예정이니 기대해주세요.