← Insights 목록
Design2026.06.28

마크다운을 컴포넌트에 넣을 때 깨지는 들여쓰기

#Astro#Markdown#Components

마크다운을 컴포넌트 안에 곱게 들여써 넣었더니 본문이 통째로 회색 코드 블록으로 변해버린 경험. 프론트엔드 개발자라면 한 번쯤 겪는 함정이다. CSS-Tricks가 2026년 6월 1일 공개한 Zell Liew의 글은 이 사소해 보이지만 끈질긴 문제를 정면으로 다룬다. 대부분의 마크다운 라이브러리가 들여쓴 공백을 ‘코드’로 오해해 <pre><code>로 감싸버리기 때문인데, 저자는 이를 프레임워크를 가리지 않고 푸는 작은 유틸과 Astro 슬롯 활용법으로 풀어낸다.

"I hit a snag when using most Markdown libraries."Zell Liew, CSS-Tricks

무슨 일인가

핵심은 ‘입력 정리’다. Splendid Labz의 markdown() 유틸은 마크다운 텍스트를 처리하기 전에 문제의 들여쓰기를 먼저 걷어낸다. inline 옵션으로 결과를 <p>로 감쌀지 말지도 고른다. 프레임워크별 연결 방식은 슬롯 처리 능력에 따라 갈린다. Astro는 Astro.slots.render()로 슬롯에 담긴 자식 콘텐츠를 문자열로 받아 유틸에 통과시키고, Svelte는 동적 슬롯 내용을 읽지 못해 props로 텍스트를 넘긴다. React·Vue는 같은 패턴을 직접 구현하면 된다. 결국 ‘어디에 마크다운을 두고, 어떻게 문자열로 꺼내느냐’가 전부다.

여러 시각

같은 문제를 Astro가 제공하는 기본기와 견주면 맥락이 분명해진다.

  • Astro 공식 문서(슬롯) — 구조의 관점. <slot/>은 외부 HTML을 끼워 넣는 자리표시자이고, Astro.slots 유틸로 슬롯 콘텐츠를 직접 렌더링·문자열화할 수 있다. 이 글의 우회법이 사실 Astro의 기본기 위에 서 있음을 보여준다.
  • Astro 공식 문서(마크다운) — 대안의 관점. 레이아웃은 compiledContent()로 마크다운을 HTML로, rawContent()로 원문 문자열을 돌려준다. 콘텐츠 양이 커지면 즉석 유틸보다 이런 네이티브 파이프라인이나 MDX가 더 견고하다는 점을 시사한다.

왜 중요한가

이 작은 문제는 ‘콘텐츠와 컴포넌트의 경계’라는 큰 주제를 건드린다. 디자인 시스템이 성숙할수록 버튼·카드 같은 UI뿐 아니라 본문 텍스트도 컴포넌트로 다뤄야 하는데, 마크다운은 공백에 민감해 ‘코드 모양’과 ‘콘텐츠 모양’의 경계가 쉽게 무너진다. 들여쓰기 하나로 렌더링이 깨지면 디자인 QA에서 잡기도 어렵다. 프레임워크마다 슬롯 모델이 달라 ‘한 번 짜서 어디서나’가 생각보다 어렵다는 현실도 함께 드러난다.

실무 적용

  • 마크다운을 컴포넌트에 넣을 땐 들여쓰기를 펴거나 전용 유틸로 정규화해, 공백이 코드 블록으로 둔갑하는 일을 막는다.
  • 슬롯에서 문자열을 꺼내는 API(Astro.slots.render 등)는 프레임워크마다 다르므로, 콘텐츠 렌더링 계층을 얇게 추상화해 갈아끼우기 쉽게 둔다.
  • 본문 분량이 늘면 즉석 변환 대신 MDX·콘텐츠 컬렉션 같은 네이티브 파이프라인으로 옮겨 빌드 타임에 안정적으로 처리한다.

Kenny의 관점

프론트엔드에서 이런 ‘공백 한 칸’ 버그가 무서운 이유는, 기능이 아니라 콘텐츠가 조용히 망가지기 때문이다. 테스트는 통과하는데 글이 코드처럼 보인다. 나는 마크다운을 다룰 때 ‘입력은 더럽고 출력은 깨끗해야 한다’를 전제로, 정규화 단계를 파이프라인 맨 앞에 못 박아 둔다. 그리고 프레임워크에 종속된 슬롯 트릭은 최소화한다 — 영리한 우회는 당장은 통하지만, 다음 사람이 왜 이렇게 짰는지 모르면 그게 곧 부채다. 콘텐츠를 컴포넌트로 다루는 시대일수록 경계를 단순하게 지키는 쪽이 오래 간다.

출처

이 글은 아래 원문을 바탕으로 Kenny가 한국어로 요약·정리한 큐레이션입니다.

원문 보기 — CSS-Tricks ↗