Next.js + MDX로 3개 국어 블로그 만들기
Next.js 14 App Router와 MDX, next-intl을 조합해서 한/영/일 3개 국어 개인 블로그를 만든 과정을 정리했다.
왜 직접 만들었나
기존 블로그 플랫폼을 다 써봤다. Medium, Velog, 티스토리. 항상 어딘가 하나씩 아쉬웠다. 다국어 지원이 안 되거나, 코드 하이라이팅이 맘에 안 들거나, 디자인 커스터마이징이 제한적이거나.
결국 내가 원하는 걸 다 넣을 수 있는 블로그를 직접 만들기로 했다.
기술 스택
App Router + SSG로 정적 사이트 생성
@tailwindcss/typography로 글 본문 렌더링
next-mdx-remote + gray-matter로 파싱
/ko, /ja, /en 라우팅 자동 처리
GitHub push → 자동 빌드/배포
시스템 설정 연동 + 수동 토글
핵심: MDX 파이프라인
MDX 파일을 읽어서 프론트매터를 파싱하고, 글 목록을 만드는 유틸리티를 작성했다.
content/[locale]/[category]/[slug].mdx 경로에서 파일을 읽는다
gray-matter로 title, date, tags 등 메타데이터 추출
next-mdx-remote가 마크다운 + JSX를 React 컴포넌트로 변환
ChatThread, BarChart 같은 MDX 컴포넌트를 매핑
빌드 타임에 모든 글을 HTML로 미리 생성 (SSG)
// src/lib/mdx.ts — 글 하나 읽기
export function getPostBySlug(locale: Locale, category: Category, slug: string) {
const filePath = path.join(contentDir, locale, category, `${slug}.mdx`);
const fileContent = fs.readFileSync(filePath, "utf-8");
const { data, content } = matter(fileContent);
return { ...data, content, readingTime: readingTime(content) };
}
포인트는 content/[locale]/[category]/[slug].mdx 구조다. 로케일과 카테고리 조합으로 파일 시스템 기반 라우팅을 구현했다. Next.js App Router의 동적 세그먼트와 1:1로 대응되니까 직관적이다.
디렉토리 구조
다국어 처리가 생각보다 까다로웠다
next-intl을 쓰면 라우팅 자체는 간단하다. /ko/dev/..., /en/dev/... 이렇게 URL에 로케일을 넣으면 된다.
문제는 콘텐츠다. 같은 글의 한국어 버전과 영어 버전이 별도 MDX 파일로 존재해야 하는데, 모든 글을 번역할 필요는 없다. 개발 글은 영어 번역 우선, 일본 여행 글은 일본어 번역 우선, 일상 에세이는 한국어 전용. 이 규칙을 파일 시스템 구조로 자연스럽게 표현할 수 있는 게 MDX 기반의 장점이다.
UI 텍스트 번역은 messages/ko.json, messages/en.json, messages/ja.json에 모아두고 useTranslations 훅으로 가져온다. 이건 크게 어렵지 않았다.
배포: Vercel + GitHub
배포는 놀라울 정도로 간단하다. GitHub 레포에 push하면 Vercel이 알아서 빌드하고 배포한다. 프리뷰 배포도 자동으로 만들어주니까 PR 단위로 확인할 수 있다.
SSG(정적 사이트 생성)로 빌드하니까 성능도 빠르다. 블로그 특성상 콘텐츠가 빌드 타임에 결정되니까 SSG가 딱 맞는다.
다음 단계
하나씩 진행하면서 다 기록할 예정이다.
다음 글: 내 API 키가 털렸다 — 이 블로그 만들면서 생긴 건 아니고, 다른 프로젝트에서 터진 사고인데... 꽤 충격적이었다.
관련 글
사고 도구에 AI가 꼭 필요한가
모든 프로덕트에 AI를 붙이는 시대. 하지만 Dimension은 AI 없이도 작동하는 사고 도구를 지향한다. 왜 그런 선택을 했는지, 그리고 이건 노트 앱과 어떻게 다른지.
HN 프론트페이지의 수학: 왜 1등이 모든 걸 먹는가
Hacker News 30만 개 글을 전수조사했다. 프론트페이지 1등은 30등보다 50배 많은 관심을 받는다. 왜? 답은 '점수'가 아니라 '위치'에 있었다.