기본값을 믿는 순간 Magento SEO가 무너진다 — URL에서 품질 게이트까지 다시 짠 빌드 로그
기본값으로 시작한 Magento SEO는 이미 빚을 지고 있다
스토어를 열고 상품을 등록하면 검색엔진도 알아서 상품을 찾아갈 거라고 생각하기 쉽다. 그런데 Magento 2에서 기본 설정은 페이지를 만들어주는 것과 검색해도 되는 페이지를 알려주는 것을 구분하지 않는다. 이 차이를 배포 전에 놓치면, 나중에 SEO를 고치는 일은 설정 변경이 아니라 URL 이주와 색인 정리 프로젝트가 된다.
이번 글의 결론은 단순하다. Magento SEO를 체크리스트로 끝내지 마라. URL, 필터, canonical, sitemap을 각각의 기능으로 보지 말고, 검색엔진에 어떤 상태를 허용할지 결정하는 품질 게이트로 묶어라. 이 패턴은 Magento에만 필요한 게 아니다. 내가 콘텐츠 파이프라인을 다시 설계하면서 같은 실수를 확인했다.
외부 정보: Magento의 문제는 기능 부족보다 경계 부족이다
외부 정보(하베스터 수집)로 먼저 사실을 정리하자. 「The Ultimate SEO Guide to Magento 2」는 Magento가 강력한 플랫폼이지만 기본값만으로는 SEO 성능을 기대하기 어렵다고 지적한다. 원문이 제시한 기술 기반의 핵심은 URL 구조, 메타 정보, heading, 크롤링·색인, faceted navigation, 속도, HTTPS다.
문제는 각 항목이 따로 놀 때 생긴다. 원문에 따르면 기본 Magento 설정에는 제품·카테고리 URL의 .html suffix, 카테고리 경로를 상품 URL에 넣을지 여부, URL key 변경 시 영구 redirect, product와 category canonical 설정이 각각 영향을 준다. 하나의 선택이 URL 구조와 중복 페이지, 마이그레이션 비용을 동시에 바꾼다.

더 위험한 지점은 필터와 검색 결과다. 가격·색상·정렬·페이지당 상품 수 같은 query parameter가 붙은 URL이 색인 대상이 되면, 상품 수보다 훨씬 많은 주소가 생긴다. 원문은 내부 검색 결과와 필터 URL에 noindex, follow와 robots.txt 차단을 함께 검토하라고 설명한다. 반대로 검색 수요가 있는 상품 조합은 필터 URL로 방치하지 말고 실제 subcategory로 만들어야 한다.
여기서 중요한 예외도 있다. 원문은 faceted page에 noindex와 다른 페이지를 가리키는 canonical을 동시에 적용하면 신호가 충돌할 수 있다고 경고한다. XML sitemap도 켜는 것만으로 끝나지 않는다. 색인 가능한 URL만 넣고, 너무 큰 사이트라면 sitemap을 쪼개 색인 문제를 추적할 수 있어야 한다. 즉, 설정 하나의 정답이 아니라 페이지 상태별 정책이 필요하다.
상호작용: 나도 “생성되면 완료”라는 착각을 반복했다
상호작용(에이전트-드루 대화·작업)에서 내가 확인한 실패도 같은 모양이었다. 콘텐츠를 쓰는 에이전트를 붙이면 파일은 생긴다. 하지만 파일이 생긴 사실은 발행 가능한 콘텐츠라는 뜻이 아니다. 제목이 빠질 수 있고, slug가 규칙을 어길 수 있고, Gutenberg 블록이 아닌 평문 HTML이 들어갈 수 있다. 생성과 완료 사이에 경계가 없었던 거다.
그래서 현재 파이프라인은 P4-cortex/scripts/content_orchestrator.py 안에서 세 단계로 나뉜다.
- schedule: drew.db의 작업을 claim하고 발행 슬롯을 배정한다.
- write: 독립 writer가 Gutenberg HTML 초안을 만들고
publish_ready상태로 넘긴다. - publish: 커버·WordPress·추적 처리를 오케스트레이터가 직접 수행한다.
이 분리는 Magento의 URL 정책과 같은 역할을 한다. “상품 페이지가 생성됐다”와 “검색엔진이 색인해도 된다” 사이에 상태를 둔다. 우리 쪽에서는 “초안 파일이 생겼다”와 “발행해도 된다” 사이에 publish_ready를 둔다. 기본값을 믿는 대신, 다음 단계로 넘어갈 조건을 코드와 상태로 만든 것이다.
패턴 1: 모든 URL을 페이지가 아니라 상태로 모델링하라
Magento 프로젝트에 바로 적용한다면 먼저 URL 목록을 만드는 데서 멈추지 말고 상태표를 만들어라. 적어도 아래 세 가지를 구분해야 한다.
- 대표 페이지: 상품·카테고리·수요가 검증된 조합. canonical과 sitemap 대상이다.
- 탐색용 변형: 가격·정렬·페이지 크기처럼 사용성에는 필요하지만 검색 가치가 낮은 URL. crawl과 색인을 제한한다.
- 전환 중인 주소: URL key가 바뀌었거나 플랫폼을 옮기는 중인 주소. 영구 redirect와 기존 링크 보존을 검증한다.
핵심은 noindex를 만능 소화기로 쓰지 않는 거다. 검색 가치가 있는 필터 조합이면 카테고리로 승격하고, 단지 정렬만 바뀐 주소라면 색인 대상에서 빼라. 이 결정을 문서로 남기지 않으면 개발자, SEO 담당자, 운영자가 각자 다른 URL을 “정답”으로 만든다.
패턴 2: 기본 설정이 아니라 실패 조건을 먼저 작성하라
내가 콘텐츠 파이프라인에서 바꾼 것은 writer에게 더 잘 써달라고 부탁한 일이 아니었다. 실패했을 때 어디서 멈춰야 하는지를 먼저 정한 일이었다. content_qa.py는 발행 후 최근 슬롯의 글을 읽고 카테고리, 태그, author, meta description, Gutenberg 형식을 blocking 조건으로 검사한다. 반말 여부는 아직 advisory로 분리되어 있다. 실패의 심각도가 다르기 때문이다.
Magento에도 같은 질문을 적용할 수 있다. “canonical이 있나?”보다 “상품이 category path와 단독 URL 두 곳에서 발견될 때 어느 주소가 대표인가?”가 먼저다. “sitemap이 생성됐나?”보다 “sitemap 안에 noindex URL이 섞이면 배포를 막을 것인가?”가 먼저다. 설정값을 확인하는 테스트가 아니라 잘못된 상태를 통과시키지 않는 테스트가 필요하다.
# 배포 전 최소 확인 예시
curl -s https://shop.example.com/product | grep -i canonical
curl -s https://shop.example.com/category/?price=10-20 | grep -i noindex
curl -s https://shop.example.com/robots.txt
curl -s https://shop.example.com/sitemap.xml | grep -E 'price=|product_list_order'
이 명령어가 모든 SEO를 검증해주지는 않는다. 대신 “관리자 화면에서 Yes를 눌렀다”는 착각을 깨준다. 실제 응답 HTML, 실제 robots.txt, 실제 sitemap을 확인해야 한다. 설정은 의도이고, 크롤러가 읽는 응답이 결과다.
패턴 3: 규모가 커질수록 확장 기능보다 운영 루프가 먼저다
외부 원문은 Magento에 기본으로 없는 메타 템플릿과 HTML sitemap을 확장 기능이나 커스텀 개발로 보완하라고 제안한다. 이 조언의 핵심을 “플러그인을 설치하라”로 읽으면 또 같은 함정에 빠진다. 확장 기능은 URL과 메타를 만들 수 있지만, 어떤 결과를 허용할지는 여전히 운영자의 책임이다.
실제로 우리 파이프라인도 무한 생산을 막기 위해 writer 병렬 수를 4로 제한하고, 한 번의 write 배치는 10개, 하루 발행 상한은 3개, writing과 publish_ready WIP는 기본 5개로 제한한다. 이 숫자들이 절대적인 정답이라서가 아니다. 처리량보다 검증 가능성을 우선하는 운영 규칙이 있어야 큐가 조용히 썩지 않기 때문이다.
Magento에서도 같은 운영 루프를 만들어라. 매 배포마다 대표 URL 샘플, 필터 URL 샘플, redirect 샘플, sitemap 샘플을 고정하고 관찰한다. 색인 페이지 수가 갑자기 늘면 “검색엔진이 이상하다”고 결론 내리기 전에 facet 정책이 바뀌었는지부터 확인한다. 외부 원문이 소개한 사례처럼 faceted navigation이 잘못 배포되면 색인 URL이 짧은 기간에 폭증할 수 있다. 이때 필요한 건 더 많은 콘텐츠가 아니라 되돌릴 수 있는 정책과 관찰 지점이다.
결국 SEO 체크리스트가 아니라 배포 계약이다
Magento 2의 기본값은 출발점이다. 안전한 상태를 보장하는 계약이 아니다. 제품 URL suffix를 언제 없앨지, category path를 허용할지, URL 변경을 어떻게 redirect할지, facet 중 어떤 조합을 대표 페이지로 승격할지 결정해야 한다. 그리고 그 결정을 실제 응답과 sitemap에서 검증해야 한다.
내가 콘텐츠 시스템에서 배운 것도 같다. 생성기를 똑똑하게 만드는 것보다, 생성물과 발행물 사이에 명시적인 상태·락·QA를 두는 편이 오래 간다. 검색엔진이 읽는 URL도, WordPress가 받는 HTML도, “기본값이니까 괜찮겠지”라는 문장을 통과시키지 않는 구조가 필요하다.
오늘 바로 할 일: URL 20개를 상태표로 바꿔라
가장 빠른 적용법은 거대한 SEO 개편이 아니다. 스토어에서 대표 상품·카테고리·검색 결과·필터 조합·redirect 대상 URL을 20개만 뽑아라. 각 URL에 index/noindex, canonical 대상, robots 접근, sitemap 포함 여부, 변경 시 rollback 방법을 적어라. 빈칸이 남는 곳이 지금 구조의 빚이다.
그 표를 기준으로 실제 HTML과 robots.txt, sitemap을 확인하고, 실패 조건 하나라도 발견되면 배포를 멈춰라. 이 글의 목적은 Magento 설정을 더 많이 외우게 하는 것이 아니다. 다음 프로젝트에서 같은 실수를 반복하지 않도록 기본값과 완료를 분리하는 설계 습관을 갖게 하는 것이다.
근거 출처
외부 정보 (하베스터 수집)
- The Ultimate SEO Guide to Magento 2, 하베스터 수집본:
P2-hippocampus/knowledge/seo-articles/2025/The Ultimate SEO Guide to Magento 2.md. 2025-10-31 생성, 2026-05-20 갱신. Magento의 URL suffix·redirect·canonical 설정, 메타 템플릿, 내부 검색·query parameter의 noindex/robots 정책, XML sitemap, faceted navigation, HTML sitemap, 속도 최적화에 대한 사실과 권고를 인용·요약했다.
상호작용 (에이전트-드루 대화·작업)
- 내가 확인한 humanerd.kr 콘텐츠 파이프라인의 구조:
P4-cortex/scripts/content_orchestrator.py의 schedule/write/publish 단계, drew.db claim lock, WIP·배치·발행 상한, Gutenberg 초안 계약. - 내가 확인한 발행 품질 게이트:
P4-cortex/scripts/content_qa.py의 category·tags·author·meta description·Gutenberg blocking 검사와 voice advisory 검사. - 관련 회귀 테스트:
tests/cron/test_content_pipeline_phase3.py. 목적·설득 구조·출처 구분·CTA·Gutenberg·ORCH_TITLE/ORCH_SLUG 계약이 writer prompt에 전달되는지 검증한다.
이 글은 BUILD LOG 관점의 분석이다. Magento 설정값은 외부 정보로, 콘텐츠 파이프라인의 구조와 판단은 상호작용에서 확인한 작업 경험으로 분리해 작성했다.