Sik.limited Logo

Headless CMS 마이그레이션 체크리스트: WordPress에서 Sanity·Strapi·Directus로 옮기기 전

WordPress에서 Headless CMS로 옮길 때 진짜로 지켜야 할 것은 글 데이터만이 아닙니다. URL·SEO·미디어·프리뷰·권한·롤백을 출시 전에 검증하는 실무 체크리스트입니다.

Sik · ·

워드프레스를 떠나는 일은 데이터를 옮기는 일만이 아닙니다. 검색에서 발견되던 주소, 편집자가 누르던 미리보기, 이미지에 붙은 맥락, 누가 무엇을 발행할 수 있는지를 새 시스템에서 다시 정하는 일에 가깝습니다.

그래서 “XML을 뽑아두면 시작”이라는 생각이 위험해요. WordPress의 WXR 내보내기는 글·페이지·커스텀 포스트 타입·댓글·커스텀 필드·분류·사용자 같은 콘텐츠 데이터를 담지만, 새 프런트엔드가 URL과 SEO 보조 기능까지 그대로 재현해주지는 않습니다. WordPress 공식 문서도 WXR을 콘텐츠 이전용 형식으로 설명합니다.

실무 커뮤니티에서 반복되는 실패는 비슷합니다. 리디렉션 이력을 너무 늦게 발견하고, SEO 플러그인이 만들던 구조화 데이터와 OG 메타를 놓치고, 실제 편집자가 프리뷰를 쓰기 시작한 뒤에야 워크플로가 비어 있음을 발견합니다. 이 글은 Sanity·Strapi·Directus 중 무엇이 더 좋은지 다시 비교하지 않습니다. 이미 옮기기로 했을 때, 검색과 운영을 잃지 않기 위해 어떤 순서로 결정해야 하는지를 정리합니다.

한 줄 결론: CMS를 먼저 고르지 말고 URL·콘텐츠 모델·발행 흐름을 먼저 고정하세요. 플랫폼은 그 결정을 구현하는 수단입니다.


먼저 멈춰야 하는 세 가지 경우

성능 문제의 원인을 아직 모른다

플러그인, 이미지 처리, 캐시, 호스팅, 테마 중 어디가 병목인지 모르는 상태에서 headless로 바꾸면 운영 복잡도만 늘 수 있습니다. 렌더링을 분리하면 효과가 있을 수 있지만 지금의 문제를 자동으로 해결하지는 않습니다. 먼저 실사용 페이지의 LCP·이미지 용량·캐시 적중률·관리자 화면 병목을 측정합니다.

새 편집 경험을 문장으로 설명할 수 없다

“더 유연한 CMS”는 요구사항이 아닙니다. 누가 초안을 만들고 검토·발행하는지, 편집 중인 글을 실제 페이지에서 어떻게 보는지, 조합형 랜딩 페이지는 어떤 블록으로 만드는지, 번역과 예약 발행은 누가 처리하는지에 답할 수 있어야 합니다.

오래된 URL의 목록과 목적지를 모른다

이 경우에는 개발을 시작하면 안 됩니다. Google은 URL이 바뀌는 사이트 이전에서 기존 URL과 새 URL의 매핑, 서버 측 영구 리디렉션, 새 canonical과 sitemap, 이전 후 모니터링을 권장합니다. 특히 여러 변경을 한 번에 하지 말라고 안내해요. CMS·URL·디자인을 동시에 갈아엎는 것은 기술적으로는 한 번의 출시지만, 검색에는 세 번의 변화입니다. Google Search Central의 사이트 이전 가이드가 기준점이 됩니다.


선택은 기능표가 아니라 운영의 중심으로 한다

운영의 중심더 자연스러운 출발점먼저 검증할 것
콘텐츠 팀이 구조화된 문서·에셋·프리뷰를 중심으로 일한다SanityStudio 입력 화면, draft/published 프리뷰, 문서 참조와 권한
개발팀이 API와 콘텐츠 타입을 백엔드처럼 통제한다Strapi콘텐츠 타입, 환경별 데이터·에셋 이전, 관리 권한과 배포 절차
기존 SQL 데이터와 운영 데이터가 핵심이다Directus기존 DB 매핑, collection·field·relation, 역할별 접근 제어

Sanity의 프리뷰는 초안과 공개본을 함께 다룰 수 있지만, 실제 프리뷰는 프런트엔드와 인증까지 포함해 설계해야 합니다. Sanity 프리뷰 문서를 먼저 확인하세요.

Strapi에서는 개발·스테이징·프로덕션 사이에서 무엇을 옮기고 무엇을 새로 만들지 정하는 일이 중요합니다. 데이터 전송 도구는 관리자 사용자·API 토큰 같은 항목을 의도적으로 제외할 수 있어, 운영 계정과 비밀값을 데이터 이관으로 해결하려 하면 안 됩니다. Strapi 데이터 전송 안내를 확인하세요.

Directus는 스키마 snapshot과 apply로 데이터 모델을 환경 간에 옮기고, apply 전 dry run으로 차이를 확인할 수 있습니다. 스키마를 코드와 함께 버전 관리하기 좋은 이유지만, 콘솔에서 바꾼 필드까지 배포 규칙에 포함해야 합니다. Directus CLI 문서를 기준으로 삼으면 됩니다.


0단계: 옮기지 않을 것까지 정리하는 인벤토리

좋은 마이그레이션의 첫 산출물은 import 스크립트가 아니라 한 장의 기준표입니다. 크롤러·Search Console·분석 도구·서버 로그·WordPress 관리자에서 아래 목록을 모아 하나의 키로 묶으세요.

필드반드시 남길 이유
기존 URL, 최종 URL, 상태 코드1:1 리디렉션과 체인·루프 검증의 기준
제목, 설명, canonical, robots검색 스니펫과 색인 정책을 비교하기 위해
H1, 본문, 내부 링크, 첨부 파일렌더링 결과와 깨진 링크를 찾기 위해
OG 이미지, 구조화 데이터, FAQ·저자 정보플러그인·테마가 제공하던 기능을 복원하기 위해
이미지 원본 URL, alt, 캡션, 사용 위치파일만 옮기고 맥락을 잃지 않기 위해
포스트 타입, 분류, 태그, 작성자, 언어새 콘텐츠 모델과 권한 설계의 입력값
발행·수정일, 조회·전환·백링크우선 이관·검수할 페이지를 정하기 위해

전체 글 수보다 예외의 수가 중요합니다. 중복 슬러그, 끝난 캠페인, PDF, 리디렉션 플러그인 규칙, 미디어 라이브러리에만 남은 이미지를 찾아내세요. 검색 트래픽·전환·외부 링크가 큰 페이지는 A등급으로 묶고 출시 전 사람의 눈으로 확인합니다.

새 사이트에 옮기지 않을 페이지는 홈페이지로 몰아 보내지 마세요. 관련 있는 대체 페이지로 보내거나, 정말 사라진 콘텐츠라면 404 또는 410을 반환합니다. Google도 무관한 홈페이지 리디렉션은 soft 404로 해석될 수 있다고 안내합니다. Google 이전 가이드를 따르세요.


1단계: WordPress의 글을 새 콘텐츠 모델로 번역한다

워드프레스의 편집 화면은 한 덩어리 본문으로 보이기 쉽습니다. 새 CMS에서는 재사용하고 검증할 단위를 먼저 나누는 편이 좋습니다. 단, 모든 문단을 필드로 쪼개지는 마세요. 에디터가 한 번도 재사용하지 않을 구조는 기술 부채가 됩니다.

글 콘텐츠라면 보통 아래면 출발할 수 있어요.

  • 공통: 제목, slug, 요약, 본문, 대표 이미지, 작성자, 발행·수정일, 상태
  • SEO: title, description, canonical override, robots, OG 이미지, 구조화 데이터에 필요한 값
  • 관계: 카테고리, 태그, 관련 글, 다국어의 원본-번역 연결
  • 본문 블록: 텍스트, 이미지, 인용, 코드, 표, CTA처럼 실제로 재사용하는 것만

샘플은 예쁜 글이 아니라 가장 못된 글을 골라야 합니다. 표·인라인 이미지·유튜브·갤러리·shortcode·ACF·다국어·공동 저자·예약 발행이 섞인 글 10개를 이관해 보세요. 이 샘플이 통과하면 대량 이관의 범위가 보입니다.

Sanity라면 import 전후 검증과 dry run을 기본 절차로 두는 편이 안전합니다. 공식 CLI도 실제 적용 전 dataset export 또는 copy로 백업하라고 안내합니다. Sanity schema and content migrations를 참고하세요.


2단계: 미디어는 파일 이전이 아니라 참조 이전이다

이미지는 가장 늦게 터지는 문제입니다. 썸네일은 보이는데 본문 인라인 이미지는 안 보이거나, alt와 캡션이 빠지고, 같은 이미지가 여러 글에서 어떻게 쓰였는지 잃어버립니다.

미디어 매핑표에는 최소한 기존 URL, 새 asset ID, 새 URL, 사용하는 문서 ID, alt와 caption을 남기세요. 파일 해시를 함께 보관하면 중복 업로드와 재실행을 줄이는 데 도움이 됩니다. 실패한 행을 다시 실행할 수 있게 작은 배치로 결과를 기록합니다.

Sanity는 대량 에셋 import를 CLI로 지원하며 같은 파일은 중복 업로드되지 않도록 처리합니다. 하지만 Media Library 파일을 문서에 연결하는 단계는 별도로 필요할 수 있어요. Sanity 에셋 import문서 연결 가이드를 함께 봐야 합니다.

Strapi와 Directus도 마찬가지입니다. 업로드가 끝났다는 것이 완료 조건이 아닙니다. 원본 이미지, 변환본, alt, 캡션, 문서 관계, CDN URL, 접근 권한까지 실제 페이지에서 확인해야 합니다.


3단계: SEO를 배포 후 점검 항목이 아니라 출시 차단 조건으로 둔다

검색은 새 CMS를 알아주지 않습니다. Google이 보는 것은 최종 HTML과 응답입니다. 그래서 SEO 검수는 콘텐츠 import가 끝난 후가 아니라, 스테이징에서 같은 URL 집합을 비교하는 일이어야 해요.

출시 전, 이 조건이 모두 참이어야 한다

  • 기존 핵심 URL은 같은 URL로 200을 반환하거나, 정확한 새 URL로 단일 홉 301/308을 반환한다.
  • 새 페이지는 self-referencing canonical을 갖고, noindex가 남아 있지 않다.
  • title, meta description, Open Graph, robots, JSON-LD가 기존 의도와 맞게 렌더링된다.
  • 내부 링크·이미지·PDF·hreflang은 새 최종 URL을 가리킨다.
  • sitemap에는 색인시키고 싶은 절대 HTTPS canonical URL만 담긴다.
  • 모바일 렌더링과 실제 봇 접근에서 인증·WAF·자바스크립트 오류가 없다.
  • 구 사이트와 신 사이트를 각각 크롤링해 200, 3xx, 4xx, canonical, robots, H1, title을 diff했다.

Google은 영구 리디렉션으로 301/308을 권하고 체인은 가능한 한 피하라고 합니다. 내부 링크와 sitemap도 새 URL을 직접 가리켜야 해요. 또한 사이트 이전이 완전히 처리되려면 Googlebot이 이전·새 URL을 모두 방문해야 하므로, 중간 규모 사이트도 몇 주가 걸릴 수 있다고 안내합니다. Redirect 가이드sitemap 가이드를 함께 확인하세요.

가장 좋은 출시 전략은 단순합니다. CMS는 바꾸되, 첫 출시에서 URL·정보 구조·카피·디자인을 같이 바꾸지 않는 것. 개선은 색인과 운영이 안정된 다음 릴리스로 미룹니다.


4단계: 권한과 프리뷰를 실제 사람에게 테스트한다

개발자가 프리뷰를 열 수 있다는 사실만으로 편집자가 일을 끝낼 수 있는 것은 아닙니다. 아래 역할로 30분짜리 사용성 리허설을 해보세요.

  • 작성자: 새 글을 만들고 이미지·SEO 필드를 채운다.
  • 검토자: 초안 URL에서 실제 화면과 메타를 확인하고 수정 요청을 남긴다.
  • 발행자: 예약 발행과 긴급 롤백을 처리한다.
  • 운영자: 작성자가 전역 설정, 리디렉션, API 비밀값을 건드리지 못하게 한다.

Sanity는 프로젝트·dataset·문서 범위까지 역할과 권한을 나눌 수 있습니다. 다만 public dataset이라면 프로젝트 구성원은 역할과 무관하게 공개 콘텐츠를 읽을 수 있다는 점을 공식 문서가 명시합니다. Sanity roles를 확인하고, 비공개 초안과 공개 데이터셋을 같은 개념으로 취급하지 마세요.


5단계: 롤백은 백업이 있다가 아니라 되돌릴 수 있다다

무언가 잘못되면 무엇을, 몇 분 안에, 누가 되돌리는지 적어두세요. 백업은 시작일 뿐이에요.

출시 전 롤백 카드

  • 이전 WordPress 사이트를 다시 가리킬 DNS·프록시·배포 설정
  • 새 프런트엔드의 직전 안정 배포 버전
  • CMS 데이터 export와 생성 시각, 에셋 목록, import 로그
  • URL 매핑 파일과 배포된 리디렉션 규칙의 버전
  • 롤백을 승인할 사람과 관측 대시보드 링크
  • 즉시 롤백 조건: 핵심 URL의 5xx, 대규모 noindex, 로그인·결제·문의 흐름 장애

Directus의 snapshot/apply는 스키마 차이를 확인할 수 있어 운영 환경 변경 관리에 도움이 됩니다. 하지만 snapshot이 콘텐츠 데이터와 프런트엔드 배포까지 대신 복구해주지는 않아요. 스키마·콘텐츠·에셋·프런트엔드·리디렉션을 각각 복구할 수 있어야 진짜 롤백입니다.


출시 후 14일: 트래픽이 아니라 이상 징후를 먼저 본다

출시일은 완료일이 아닙니다. 다음 2주 동안은 새 글 발행이나 대형 디자인 변경을 멈추고, 이관의 결과만 관찰하세요.

시점확인할 것
출시 직후핵심 URL 표본의 상태 코드, canonical, robots, 메타, 구조화 데이터, 로그인·폼·프리뷰
24시간서버 오류, 404 증가, 리디렉션 체인·루프, 깨진 이미지와 내부 링크
3~7일Search Console의 sitemap 처리, 색인·크롤링 오류, 브랜드·핵심 쿼리 노출 변화
14일이전 URL의 트래픽·리디렉션 로그, 새 URL 색인 추세, 콘텐츠 팀 발행 시간과 오류

Google은 이전 후 Search Console에서 sitemap·색인 상태·크롤링을 관찰하라고 하고, 리디렉션은 일반적으로 적어도 1년 유지하라고 권장합니다. 사이트 이전 후 모니터링 지침을 운영 문서에 연결해두세요.


위험 레지스터: 문제 생기면 보자를 막는 표

위험가장 이른 신호예방첫 대응
누락된 이전 URL404·유입 급감·외부 링크 오류sitemap·로그·GSC·리디렉션 규칙에서 URL 통합URL 매핑 추가, 단일 홉 영구 리디렉션
SEO 플러그인 기능 소실JSON-LD·OG·title 차이기존 HTML과 새 HTML을 페이지별 비교메타·구조화 데이터 렌더러 보완
미디어 참조 단절본문 이미지 404·alt 누락asset ID와 문서 ID 매핑표실패 배치 재실행, 참조 패치
스키마 과설계편집자가 필드 입력을 회피가장 복잡한 샘플 10개로 먼저 테스트필드 통합, 블록 축소
프리뷰·권한 공백메일·메신저로 승인 우회역할별 리허설과 체크리스트프리뷰 URL·권한 정책 보완
되돌릴 수 없는 배포롤백 담당·절차 불명출시 전 복구 훈련프런트엔드부터 안정 버전으로 복귀

결국 옮기는 것은 CMS가 아니라 책임의 위치다

WordPress는 많은 것을 플러그인과 테마 안에 감춰둡니다. Headless CMS는 그 책임을 콘텐츠 모델, API, 프런트엔드, 배포 파이프라인으로 꺼내 놓습니다. 그래서 더 자유로워질 수 있지만, 자동으로 단순해지지는 않아요.

잘 끝난 마이그레이션은 “Sanity로 갔다” 혹은 “Directus를 쓴다”로 설명되지 않습니다. 기존 URL은 그대로 살아 있고, 편집자는 전보다 덜 불안하게 발행하며, 새 페이지가 검색과 사용자에게 같은 약속을 지키는 상태로 설명됩니다.

인벤토리, 콘텐츠 모델, 작은 샘플 이관, URL·SEO 검증, 실제 편집자 리허설, 롤백 훈련, 그리고 조용한 출시. 이 순서가 먼저입니다. 도구는 그 뒤에 고르면 됩니다.

참고한 공식 문서

최신 글