안녕하세요, 정규 시리즈에서는 차마 다 풀지 못했던 날것의 코딩 삽질기를 들고 온 디자인 엔지니어 올리브입니다. 🌿

Headless 워드프레스 아키텍처는 겉보기엔 아주 우아합니다. 백엔드와 프론트엔드가 완벽하게 분리되어 있으니까요. 하지만 프론트엔드 개발자가 워드프레스 API(GraphQL)를 찔러서 본문 데이터를 받아오는 순간, 아주 당혹스러운 현실과 마주하게 됩니다.

바로 "<p>안녕하세요</p><h2>제목입니다</h2>" 처럼, 워드프레스가 뱉어낸 거대한 HTML 문자열 덩어리를 통째로 받아들여야 한다는 사실이죠.


1. “위험하다고요? 제가 통제하면 안전합니다” 🦠

리액트(React)나 Next.js에서 이 HTML 문자열을 화면에 그대로 뿌리려면 이름부터 무시무시한 **dangerouslySetInnerHTML**이라는 속성을 써야 합니다.

// 이름은 무섭지만, 가장 확실하고 가벼운 렌더링 방식
<article 
  className="post-content" 
  dangerouslySetInnerHTML={{ __html: post.content }} 
/>

이 코드를 쓰는 순간, 워드프레스에서 작성한 텍스트, 이미지, 인용구들이 통째로 화면에 쏟아집니다. 문제는 이 불청객들이 제가 리액트 컴포넌트로 예쁘게 짜둔 규칙을 전혀 모른다는 점이죠. 기본 폰트로 렌더링된 거대한 텍스트, 레이아웃을 뚫고 나가는 이미지… 처음 화면을 띄웠을 때의 그 처참함은 디자인 엔지니어의 심기를 매우 불편하게 만듭니다.


2. 진짜 챌린지: CSS로 거대한 덩어리 조각하기 ⚔️

어떤 개발자들은 이 HTML을 전부 해체해서 리액트 컴포넌트로 바꾸는 복잡한 라이브러리를 씁니다. 하지만 저는 불필요한 연산으로 성능을 깎아먹는 ‘오버 엔지니어링’을 피하고 싶었습니다. 대신 가장 직관적이고 강력한 CSS 시스템으로 이 덩어리를 깎아내기로 결심했죠.

도마 위에 오른 HTML 덩어리를 요리하기 위해, 저는 .post-content라는 거대한 래퍼(Wrapper) 안에 아주 집요하고 촘촘한 CSS 규칙들을 세우기 시작했습니다.

  • 타이포그래피의 위계: h1, h2, h3의 여백(Margin)을 0.1rem 단위로 조정해 글의 호흡을 맞췄습니다.
  • 세이지 그린 포인트: 일반적인 <a> 태그(링크)나 <blockquote>(인용구)가 등장하면, 제가 설정한 프로젝트의 고유 컬러(세이지 그린)가 자동으로 스며들도록 글로벌 변수를 꽂아 넣었습니다.
  • 미쳐 날뛰는 이미지 제어: 워드프레스가 멋대로 던진 <img> 태그가 모바일 화면을 뚫고 나가지 않도록 max-width: 100%, height: auto를 걸고, 부드러운 border-radius를 추가해 제 디자인 시스템에 억지로(?) 편입시켰습니다.

3. 마치며: ‘진짜’ 통제권은 우회하지 않는 정면 승부에서 나옵니다 🧘‍♂️

dangerouslySetInnerHTML을 쓰는 것은 어떻게 보면 워드프레스의 날것을 그대로 수용하는 타협처럼 보일 수 있습니다. 하지만 그 안에서 일어나는 모든 시각적 결과물을 CSS로 100% 통제해 냈을 때, 저는 진정한 의미의 ‘디자인 엔지니어링’을 경험했습니다.

불필요한 자바스크립트 파싱(Parsing) 연산을 줄여 프론트엔드의 가벼움을 유지하면서도, 0.1px의 시각적 오차도 허용하지 않는 견고한 화면. 이 험난했던 스타일링 챌린지는 저를 한 단계 더 성장한 픽셀의 지배자로 만들어 주었습니다.


올리브의 한 줄 요약: “데이터는 날것(Raw)으로 받되, 화면은 0.1px의 오차 없이 우아하게 통제하세요. 그게 진짜 실력입니다.” 🌿