MDX로 기술 블로그 만들기 — 코드 블록부터 인터랙티브 컴포넌트까지
마크다운에 JSX를 더한 MDX로 기술 블로그를 만드는 실전 가이드.
MDX란
MDX는 마크다운 안에서 JSX 컴포넌트를 사용할 수 있게 해주는 포맷이다. 일반 마크다운의 가독성을 유지하면서, 필요한 곳에 인터랙티브 요소를 끼워넣을 수 있다.
# 일반 마크다운 제목
일반 마크다운 문단.
<CustomChart data={chartData} />
다시 일반 마크다운으로 이어진다.
기술 블로그에서 MDX가 유용한 이유: 코드 예제, 비교 테이블, 인터랙티브 데모를 마크다운 글 안에 자연스럽게 배치할 수 있다.
Astro에서 MDX 설정
Astro는 MDX를 공식 지원한다.
npx astro add mdx
astro.config.mjs에 플러그인이 추가된다:
import mdx from '@astrojs/mdx';
export default defineConfig({
integrations: [mdx()],
});
이후 .mdx 파일을 Content Collection에 넣으면 자동으로 처리된다.
Content Collection으로 글 관리
글마다 필요한 메타데이터를 Zod 스키마로 정의한다.
const blogCollection = defineCollection({
loader: glob({
pattern: '**/*.mdx',
base: './src/content/blog',
}),
schema: z.object({
title: z.string(),
description: z.string(),
date: z.string(),
category: z.enum(['dev', 'tutorial', 'insight']),
tags: z.array(z.string()),
}),
});
frontmatter에 필수 필드가 빠지면 빌드가 실패한다. 런타임 에러 대신 빌드 타임에 잡히므로 훨씬 안전하다.
글 작성 패턴
---
title: "Rust로 AES-256 암호화 구현하기"
description: "PBKDF2 키 파생부터 nonce 관리까지."
date: "2026-03-12"
category: "tutorial"
tags: ["Rust", "AES-256", "암호화"]
---
## 왜 AES-256-GCM인가
시크릿 매니저에서 암호화 알고리즘을 고를 때...
## 마스터 패스워드에서 키 파생
PBKDF2로 키를 파생한다.
\`\`\`rust
fn derive_key(password: &str, salt: &[u8]) -> [u8; 32] {
// 구현
}
\`\`\`
코드 블록에 언어를 명시하면 자동으로 신택스 하이라이팅이 적용된다. Astro는 Shiki를 내장하고 있어 별도 설정 없이 동작한다.
MDX에서 주의할 점
중괄호 이스케이프
MDX는 중괄호를 JSX 표현식으로 해석한다. 일반 텍스트에서 중괄호를 쓰려면 코드 블록 안에 넣거나 백틱으로 감싸야 한다.
<!-- 에러: JSX로 해석됨 -->
fallback 설정은 { en: 'ko' } 형태다.
<!-- 정상: 백틱으로 감싸기 -->
fallback 설정은 `{ en: 'ko' }` 형태다.
HTML 엔티티
<, > 같은 문자도 JSX 태그로 해석될 수 있다. 코드 블록 밖에서는 <, >로 이스케이프하거나 백틱으로 감싼다.
스타일링
글 본문의 스타일은 .prose-custom 클래스로 제어한다.
.prose-custom h2 {
font-size: 1.25rem;
font-weight: 700;
margin-top: 3rem;
border-bottom: 1px solid var(--color-border);
}
.prose-custom p {
color: var(--color-text-secondary);
line-height: 1.9;
}
.prose-custom code {
font-family: var(--font-mono);
background: var(--color-bg-elevated);
padding: 0.2rem 0.5rem;
border-radius: 4px;
}
Tailwind의 @tailwindcss/typography 플러그인을 쓸 수도 있지만, 디자인 토큰과의 일관성을 위해 직접 정의하는 게 제어하기 쉽다.
이미지 처리
MDX에서 이미지는 마크다운 문법을 그대로 쓴다.

Astro의 Image 컴포넌트를 사용하면 자동 최적화(WebP 변환, 리사이즈)를 적용할 수 있다.
글 목록 페이지
---
import { getCollection } from 'astro:content';
const posts = (await getCollection('blog'))
.sort((a, b) =>
new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
);
---
{posts.map((post) => (
<article>
<a href={`/blog/${post.id}/`}>
<h2>{post.data.title}</h2>
<p>{post.data.description}</p>
</a>
</article>
))}
getCollection으로 모든 글을 가져와서 날짜 역순 정렬. 페이지네이션이 필요하면 Astro의 paginate 함수를 사용한다.
정리
MDX + Astro Content Collection 조합은 기술 블로그의 최적 스택이다. 마크다운의 편리함, JSX의 유연함, Zod의 타입 안전성을 모두 가져갈 수 있다. 글 하나 추가하는 건 MDX 파일 하나 만드는 것으로 끝난다.