개발을 하다 보면 마크다운 문서에 인터랙티브한 React 컴포넌트를 섞고 싶을 때가 있을 수 있다.
(ex. 문서 안에 버튼을 넣거나, 경고 박스를 커스텀 컴포넌트로 만들고 싶을 때)
그럴 때 유용하게 쓰이는 게 바로 MDX이다 🍹
✨ MDX란?
MDX는 Markdown + JSX이다.
즉, 마크다운 문법 안에서 React 컴포넌트를 직접 사용할 수 있는 포맷을 의미한다.
직접 예시로 확인해보자면, 다음과 같은 느낌이다.
# 안녕하세요
이건 일반 마크다운입니다.
<Button>눌러보세요!</Button>
+ markdown 문법 #과 컴포넌트 Button이 동시에 존재하는 특이한 문법이다
🚀 Next.js 15에서 MDX 사용하는 방법
그렇다면 이번에는 App Router기반 Next.js 15버전에서 직접 MDX를 써보고자 한다.
먼저 필요한 패키지를 설치한다.
yarn add @next/mdx @mdx-js/loader @mdx-js/react
그리고 이제 next.js의 webpack 설정을 건드려주자.
⚙️ next.config.js 설정
// next.config.ts
import withMdxCreate from '@next/mdx';
import type { NextConfig } from 'next';
const withMDX = withMdxCreate({
// Optionally provide remark and rehype plugins
options: {
// If you use remark-gfm, you'll need to use next.config.mjs
// as the package is ESM only
// https://github.com/remarkjs/remark-gfm#install
remarkPlugins: [],
rehypePlugins: [],
},
extension: /\.mdx?$/,
});
export default withMDX(nextConfig);
(옵션으로 remark 플러그인과 rehype 플러그인을 설정해줄 수 있는데, remark는 markdown processor로 마크다운 문법을 지원하고자 사용된 플러그인이다. 추가 설정을 원한다면, 이곳에서 설정할 수 있다.)
(rehype 플러그인은 remark와 비슷한 용도로 사용되는데, 이쪽은 html을 지원하기 위한 플러그인으로, 동일하게 추가 설정을 해줄 수 있다)
설정을 끝마친 뒤, 직접 next.js 프로젝트에서 mdx를 렌더링해볼 수 있다.
일단, 실제로 content.mdx라는 파일을 만들어 다음과 같이 작성해보자.
markdown 문법과 JSX 문법이 혼재된 코드를 다음과 같이 작성할 수 있다.
import { Button } from './Button';
# 문서 페이지입니다
이건 MDX에서 작성된 문서입니다. 아래는 커스텀 버튼입니다:
<Button>클릭하세요</Button>
# Button 컴포넌트는 다음과 같이 작성한다.
import React, { FC, PropsWithChildren } from 'react';
interface ButtonProps {}
export const Button: FC<PropsWithChildren<ButtonProps>> = ({ children }) => {
const handleClick = () => {
alert('Button clicked!');
};
return (
<div role="button" onClick={handleClick}>
{children}
</div>
);
};
그리고 실제 페이지를 작성하여 잘 렌더링되는지 테스트해볼 수 있다.
'use client';
import dynamic from 'next/dynamic';
import React from 'react';
const SampleContent = dynamic(() => import('./content.mdx'));
// with webpack 5, didn't work in turbopack
const MdxPage = () => {
return (
<div>
<h1>MDX Page</h1>
<SampleContent />
</div>
);
};
export default MdxPage;
실행해보면, mdx로 작성한대로 잘 화면이 뜨는 것을 볼 수 있다 ✨
버튼을 클릭해보면, 기능도 잘 동작한다.
+ 다면, 이번 구현에서 원래 사용하던 터보팩 설정을 끄고 진행을 하였다.
webpack에서의 설정은 레퍼런스도 많고 비교적 간단했는데 터보팩에서의 설정은 레퍼런스가 많지 않고, 동작에 대한 신뢰성이나 이슈가 좀 있는 상태인 것 같았다... 💧
💘 직접 작성한 코드
https://github.com/citron03/practice-next-15/commit/5bca059534b9f9da323de97bac5a1990c192d3bd
feat(mdx): setting mdx with next.js · citron03/practice-next-15@5bca059
"lint:css": "stylelint '**/*.{css,scss,sass}' --fix"
github.com
🌠 참고자료
Markdown for the component era | MDX
MDX lets you use JSX in your markdown content. You can import components, such as interactive charts or alerts, and embed them within your content. This makes writing long-form content with components a blast.
mdxjs.com
https://github.com/remarkjs/remark-gfm#install
GitHub - remarkjs/remark-gfm: remark plugin to support GFM (autolink literals, footnotes, strikethrough, tables, tasklists)
remark plugin to support GFM (autolink literals, footnotes, strikethrough, tables, tasklists) - remarkjs/remark-gfm
github.com
remark
Markdown processor powered by plugins
remark.js.org
https://github.com/rehypejs/rehype
GitHub - rehypejs/rehype: HTML processor powered by plugins part of the @unifiedjs collective
HTML processor powered by plugins part of the @unifiedjs collective - rehypejs/rehype
github.com
https://github.com/vercel/turborepo/issues/6365
[turborepo] mdx files don't cause rebuild · Issue #6365 · vercel/turborepo
What version of Turborepo are you using? 1.10.16 What package manager are you using / does the bug impact? pnpm What operating system are you using? Linux Describe the Bug MDX Files Not Triggering ...
github.com
'React' 카테고리의 다른 글
Controlled 컴포넌트와 UnControlled 컴포넌트 😊 공통 컴포넌트 고민해보기 (0) | 2025.07.13 |
---|---|
🧩 Rspack 기반 Module Federation 튜토리얼 (React 기반 MFA) (0) | 2025.06.19 |
React를 사용할 때, HTML을 직접 삽입하기 - dangerouslySetInnerHTML 사용 예제 (0) | 2025.04.20 |
React에서 XState 간단 사용 후기 😊 (0) | 2025.02.13 |
React Compiler를 직접 사용해보기 🎶 (with. next 15) (1) | 2024.12.10 |