[연재] × 중복 콘텐츠 — canonical을 못 거는 플랫폼
한 줄이면 된다고 했습니다
검색 쪽을 정리하다가 막힌 데가 하나 있었습니다. 같은 글이 네이버 블로그에도 있고 제 사이트에도 있는 상태요. 이걸 어떻게 푸냐고 물었더니 답이 3초 만에 나왔습니다.
"원본 쪽 주소를 canonical 로 걸어주세요. 머리에 한 줄만 넣으면 됩니다."
틀린 답이 아닙니다. 이게 교과서고, 이 문제의 정답이 진짜로 저거예요. 검색 관련 문서를 아무거나 열어봐도 똑같이 적혀 있습니다.
그래서 그 한 줄을 넣으러 갔습니다.
그리고 넣을 데를 못 찾았습니다.
이번 편은 그 얘기입니다. 정답을 알고 있는데 그 정답을 쓸 수 있는 자리가 없을 때, 그러면 무엇을 하느냐요.

canonical 이 뭐냐면요
용어부터 풀고 갈게요. 개발 용어를 그대로 두면 이 편이 통째로 안 읽힙니다.
웹페이지는 두 부분으로 되어 있습니다. 눈에 보이는 본문이 있고, 눈에 안 보이는 머리말이 따로 있어요. 머리말에는 사람한테 보여줄 게 아니라 기계한테 알려줄 것들이 들어갑니다. 이 글의 제목은 뭐고, 요약은 뭐고, 대표 사진은 뭔지 같은 거요. 카톡에 링크를 붙였을 때 뜨는 미리보기가 바로 이 머리말을 읽어서 만들어지는 겁니다.
canonical 은 그 머리말에 들어가는 한 줄인데, 뜻이 이렇습니다.
"이 글의 진짜 주소는 저쪽입니다. 지금 보고 있는 이 주소 말고요."
같은 글이 두 군데 있을 때, 한쪽이 손을 들고 "저는 사본입니다, 원본은 저쪽이에요"라고 말해주는 장치예요. 검색엔진은 그 말을 듣고 원본 쪽으로 평가를 몰아줍니다. 사본 쪽에 쌓인 점수까지 원본으로 넘겨주고요.
그러니까 제 상황에 딱 맞는 도구였습니다. 네이버 글에 "원본은 victor-house.com" 한 줄만 넣으면 끝나는 일이었어요.
제 사이트에는 296장 전부에 들어 있습니다
먼저 제 쪽부터 보여드릴게요. 제 사이트를 만드는 코드에는 이런 줄이 하나 있습니다.
<link rel="canonical" href="{BASE_URL}{path}">
페이지 틀을 찍어내는 함수 안에 박혀 있어서, 글이든 도구든 목록이든 모든 페이지에 자동으로 한 줄씩 들어갑니다. 제가 매번 챙기는 게 아니라 찍어낼 때 같이 딸려 나오는 구조예요.
실제로 세어봤습니다.
$ find . -name '*.html' | wc -l
296
$ grep -rl 'rel="canonical"' . | wc -l
296
296장 중 296장. 빠진 게 없습니다. 지금 살아 있는 페이지 아무거나 열어서 확인해도 이렇게 나오고요.
$ curl -s https://victor-house.com/posts/260819-.../ | grep canonical
<link rel="canonical" href="https://victor-house.com/posts/260819-연재-배포-스크립트-6개를-1개로/">
제가 코드를 갖고 있는 쪽은 이렇게 됩니다. 한 줄 넣고, 전부 들어갔는지 세어보고, 실제 주소로 확인하면 끝이에요.

내 글인데 내 머리가 아니었습니다
문제는 반대쪽입니다.
네이버 블로그에는 2024년 2월부터 쌓인 글이 있습니다. 지금 전체보기가 290개예요. 이 글들은 전부 제가 쓴 제 글입니다. 그런데 그 페이지의 머리말은 제가 만든 게 아닙니다.
블로그에서 제가 편집할 수 있는 건 본문뿐이에요. 제목 쓰고, 사진 넣고, 글 쓰고, 태그 답니다. 머리말은 네이버가 만들어서 붙입니다. 거기에 뭘 넣을지는 제가 정하는 게 아니고요.

이게 그 블로그입니다. 왼쪽에 카테고리가 죽 있고 전체보기 290개죠. 화면상으로는 제 것 같지만, 화면 뒤쪽은 제 것이 아닙니다.
이게 얼마나 남의 집인지는 주소를 뜯어보면 바로 나옵니다. 제 협찬 글 하나를 예로 들게요. 이 글의 주소는 blog.naver.com/kosehun/223631879084 인데요, 이 주소로 받아오는 페이지에는 글 내용이 안 들어 있습니다. 겉장만 옵니다. 본문은 PostView.naver?blogId=kosehun&logNo=... 라는 다른 주소로 따로 있고, 겉장이 그걸 안에다 불러다 끼워 넣는 구조예요.
겉장과 본문의 머리말이 서로 다른 말을 합니다.
겉장 <meta name="robots" content="noindex,follow"/>
본문 <meta name="robots" content="index,follow"/>
noindex 는 "이 페이지는 검색 결과에 넣지 마세요", index 는 "넣으세요"입니다. 그러니까 제가 아는 주소, 제가 남한테 알려주는 주소, 카톡에 붙이는 주소는 "검색에 넣지 마세요"라고 적힌 껍데기고, 실제로 검색에 잡히는 건 제가 평소에 볼 일도 없는 안쪽 주소예요.
이 구조를 알고 나니까 canonical 얘기가 좀 우스워졌습니다. 제가 그 한 줄을 넣고 싶어도, 어느 페이지의 머리에 넣을 건지부터가 제 손 밖이거든요.
'canonical' 이 세 번 나오긴 했습니다
여기서 한 번 속을 뻔했습니다.
진짜로 없는지 확인하려고 본문 페이지를 통째로 받아서 canonical 이라는 글자를 세어봤어요. 결과가 이렇게 나왔습니다.
$ grep -c canonical 본문.html
3
3건. 숫자만 보면 "있네?" 소리가 나오는 자리입니다. 여기서 멈췄으면 "네이버도 canonical 을 걸어놨구나" 하고 넘어갔을 거예요.
세 군데를 다 열어봤습니다. 셋 다 이렇게 생겼더라고요.
data-canonical-url="https://blog.naver.com/kosehun/223631879084"
머리말이 아니라 본문 안에 있는 공유 버튼에 붙은 값이었습니다. '이 글 주소 복사하기'를 눌렀을 때 복사될 주소요. 게다가 가리키는 곳이 네이버 자기 주소입니다. 제 사이트가 아니라요.
검색엔진이 읽는 <link rel="canonical"> 은 0건이었습니다.
이거 별거 아닌 것 같은데, 저는 이 대목이 이번 편에서 제일 중요했다고 봅니다. 개수를 세는 건 기계가 잘합니다. 그 3건이 무엇인지는 열어봐야 알아요. 세어서 나온 숫자를 답으로 읽으면 정확히 반대되는 결론이 나오는 자리였습니다.
관리 메뉴를 다 뒤졌습니다
머리말에 못 넣는다면 플랫폼이 대신 주는 스위치라도 있을 것 같았습니다. "이 블로그는 검색엔진이 수집하지 마세요" 같은 거요. 그런 설정을 주는 서비스들이 있거든요.
블로그 관리 메뉴를 처음부터 끝까지 다 열어봤습니다. 결론은 이렇습니다.
- 블로그 전체를 검색에서 빼는 스위치는 없습니다.
- 대신 글마다 '검색허용' 체크박스가 하나씩 있습니다.
즉 방법이 아예 없는 건 아니에요. 있긴 있는데, 글 하나씩 열어서 수정 → 발행 설정 → 체크 해제 → 발행을 해야 합니다. 290편이 있으니 그걸 280번쯤 반복해야 하는 거고요.
정리하면 이렇습니다.
| 제 사이트 | 네이버 블로그 | |
|---|---|---|
| 머리말 편집 | 됩니다 | 안 됩니다 |
| canonical | 296장 전부 | 0건 |
| 검색 수집 설정 | 코드로 한 번에 | 글마다 체크박스 하나 |
| 전체 끄기 | 됩니다 | 스위치 없음 |
| 290편에 적용하려면 | 한 줄 고치고 배포 | 손으로 280번 |
표준 해법이 그 플랫폼에서는 없는 기능이었습니다. 이게 × 편인 이유예요.
280번 손으로 끄면 되는 일이었는데
그래서 손으로 끄기로 했었습니다. 실제로 협찬 글 55편을 골라서 목록까지 만들었어요. 날짜·제목·주소를 한 줄씩 적고, 맨 위에 작업 순서를 붙여놨습니다.
그러고 4분 뒤에 접었습니다.
이 얘기는 앞 회차에서 한 번 했으니 결론만 다시 적을게요. 체크를 끄는 순간 파는 게 협찬 글의 검색 노출 전부였습니다. 협찬사가 돈을 주고 산 게 '게재'가 아니라 '노출'인데, 계약서 글자만 지키고 산 물건을 없애는 짓이었어요.
여기서 제가 배운 건 좀 다른 겁니다.
도구가 없을 때 사람 손으로 흉내내는 방법은 대개 존재합니다. 280번 클릭하면 되고, 하루 이틀이면 끝나요. 문제는 그 흉내가 원래 도구랑 같은 물건이 아니라는 거예요. canonical 은 "원본은 저쪽"이라고 알려주는 장치인데, 검색허용 체크 해제는 그냥 꺼버리는 장치입니다. 알려주는 것과 없애는 건 다른 일인데, 손으로 하다 보면 그 차이가 안 보입니다. 둘 다 "중복이 사라진다"는 같은 결과처럼 보이거든요.
기계적으로 대체 가능하다는 게 값까지 같다는 뜻은 아니었습니다.

지금 네이버 협찬리뷰 칸입니다. 51개 그대로 있고, 검색허용도 그대로 켜져 있습니다.

이게 아까 머리말을 뜯어봤던 그 글이에요. 2024년 10월 글인데 지금도 검색에 잡힙니다.
질문을 바꿨습니다
여기서 며칠 멈춰 있었습니다. 넣을 자리가 없다는 것도 알았고 손으로 하면 안 된다는 것도 알았는데, 그럼 뭘 하냐가 안 나왔어요.
빠져나온 건 질문을 바꾸고 나서입니다.
- (X) 겹친 글에 원본 표시를 어떻게 하나
- (O) 애초에 왜 겹치나
canonical 은 이미 겹쳐버린 뒤에 쓰는 반창고입니다. 겹치는 게 전제예요. 그런데 저는 그걸 표준 해법이라고만 알고 있어서, 겹친 상태를 당연한 조건으로 놓고 그 위에서만 답을 찾고 있었습니다.
겹치는 이유를 하나씩 적어보니 세 가지였어요.
1. 네이버에 있던 글을 사이트로 옮겨놨다 → 옮긴 만큼 그대로 겹친다 2. 그 옮기는 장치가 매일 아침 자동으로 돌고 있다 → 앞으로도 계속 겹친다 3. 사이트에 쓴 글을 네이버에도 올린다 → 새로 쓰는 글까지 겹친다
셋 다 canonical 로 표시할 문제가 아니라, 겹치지 않게 만들 문제였습니다. 표시할 도구가 없으니까 어쩔 수 없이 이쪽으로 온 건데, 와서 보니 이쪽이 원래 맞는 길이었어요.
겹칠 수 없는 것은 표시할 필요도 없습니다
제일 먼저 정리된 건 도구였습니다.
제 사이트에 있는 것들 중에는 블로그 글로는 애초에 만들 수 없는 것들이 있어요. 그런 건 겹칠 수가 없습니다. 겹칠 수 없으면 중복도 없고, 중복이 없으면 canonical 도 필요 없어요.

카드 지갑입니다. 카드사 이름 옆에 장수가 붙어 있죠. 신한 182, KB국민 173, NH농협 120, 삼성 101, 현대 100, 롯데 94… 이걸 카드사별로 눌러서 걸러 보는 화면이에요. 블로그 글로 옮기려면 카드 한 장씩 사진 붙이고 설명 쓰고 해야 하는데, 그러면 그건 다른 물건입니다.

지분·지배구조도 마찬가지고요. 삼성 그룹 계열사 66개(상장 18), 총수 일가 5명, 순환출자 고리 1개. 오른쪽에 경제적 소유 17.31%, 지배 의결권 74.3%, 괴리 4.3배라고 떠 있습니다. 이 숫자들은 눌러서 계열사를 바꾸면 같이 바뀌어요.

기술사 스터디의 첫 화면은 출제 경향 히트맵입니다. 세로가 대분류, 가로가 120회부터 139회까지고, 칸 색이 진할수록 그 회차에 많이 나왔다는 뜻이에요. 오른쪽 끝 합계를 보면 철근콘크리트 140, 건설관리 105, 철골 92, 마감 83입니다.

육아휴직 계산기는 통상임금을 넣으면 월별 수령액과 누적선이 그려집니다. 지금 화면은 300만원을 넣은 결과인데 12개월에 23,100,000원이라고 나오네요.

성경 아틀라스는 지형도 위에 두 겹을 덮습니다. 하나는 언약공동체, 하나는 영향력이 미친 땅이에요.
이 다섯 개 다 네이버에 대응물이 없습니다. 경쟁 자체가 없는 층이에요. 검색엔진이 "둘 중 어느 쪽이 원본이지?" 하고 헷갈릴 일이 아예 안 생깁니다.

이 연재도 같습니다. 사이트에만 있고 네이버에는 없어요.
왕복을 끊는 데는 태그가 아니라 파일 한 줄이 필요했습니다
두 번째로 정리한 게 자동으로 겹치는 경로입니다.
네이버 글을 사이트로 옮겨오는 장치가 매일 아침 자동으로 돌고 있었어요. 처음엔 이게 맞았습니다. 네이버가 원본이고 사이트가 사본이던 시절이니까요. 그런데 원본이 사이트 쪽으로 넘어오고 나서는 이게 같은 글을 되돌려 보내는 짓이 됩니다.
특히 무서웠던 게 왕복이에요. 사이트에 쓴 글을 네이버에 올리면, 다음 날 아침 그 장치가 그걸 다시 사이트로 가져옵니다. 원본 옆에 사본이 나란히 생기는 거죠. 제가 아무것도 안 해도 매일 아침 중복이 하나씩 늘어나는 구조였습니다.
이걸 막은 방법이 canonical 이 아니라 파일에 카테고리 이름 한 줄 적기였습니다. 안 가져올 목록에 Victor House 를 넣었어요. 이 이름은 네이버 쪽 카테고리 이름과 글자 그대로 같아야 합니다.
파일에 이유까지 같이 적어놨습니다.
victor-house.com 에 올린 글을 네이버에서 알리는 요약·링크 글이 모이는 곳. 전문은 홈페이지에만 두고 네이버엔 간추린 글만 올린다 — 그래야 같은 글이 두 곳에 생기지 않는다. 이 카테고리를 가져오면 요약글이 홈페이지에 얇은 글로 도로 들어오므로 반드시 제외한다.
그 아래에 ★ 표시로 한 줄 더 붙였고요.
★협찬 글은 여기 넣지 말 것 — 협찬은 네이버 본문 게재가 계약 조건이다.
이 두 줄이 제가 canonical 대신 쓴 겁니다. 태그가 아니라 문이 어느 방향으로 열려 있는지를 정한 것에 가까워요.

지금 네이버의 그 칸입니다. 2개의 글이 들어 있고, 사이트 글을 복사해 붙인 게 아니라 거기 맞게 따로 쓴 글이에요. 화면에 보이는 건 스위치 값을 정리하다가 나온 얘긴데, 같은 축이 350원하고 5,180원으로 동시에 적혀 있길래 봤더니 뒤엣것이 10개 묶음값이더라는 내용입니다.
안 푼 걸 안 풀었다고 적어뒀습니다
여기까지 하고도 안 풀린 게 남았습니다.
내돈내산 리뷰가 그렇습니다. 네이버에 105편, 사이트에 103편. 이건 그냥 겹칩니다. 협찬처럼 계약이 걸린 것도 아니고 도구처럼 한쪽에만 있는 것도 아니라서, 위에서 만든 규칙 어디에도 안 걸려요.
여기서 결론이 "나중에 하겠습니다"로 끝나면 그건 안 한 거잖아요. 그래서 안 하는 것으로 정하고 조건을 적었습니다.
- 중복이 있다고 벌을 받는 게 아닙니다. 검색엔진이 둘 중 하나를 골라서 그쪽만 내보낼 뿐이에요. 골라주는 걸 제가 못 정하는 게 문제지, 없던 손해가 생기는 게 아닙니다.
- 지금 사이트는 검색 유입이 사실상 0입니다. 잃을 게 없는 쪽에서 280번 클릭할 이유가 없어요.
- 서치콘솔이 실제로 "이 글이 중복이라 색인에서 뺐다"고 알려주면 그때 상위 20편만 손봅니다.
'아직 안 했다'와 '안 하기로 했다'는 다릅니다. 앞엣건 잊어버리면 사라지고, 뒤엣건 조건이 오면 다시 켜집니다. 조건을 적어두는 데 한 줄이면 되는데 이걸 안 적으면 몇 달 뒤에 똑같은 고민을 처음부터 다시 하게 되더라고요.
사람이 붙잡은 곳
이번 편에서 사람 손이 필요했던 자리가 세 군데였습니다.
하나. "canonical 로 하세요"가 이 플랫폼에서 되는지 아무도 확인 안 했습니다. 답 자체는 완벽했어요. 검색 문서에 그렇게 적혀 있고, 다른 데선 그게 정답입니다. 다만 그 답은 "내가 머리말을 편집할 수 있다"를 전제로 깔고 있는데, 그 전제가 여기선 안 맞았습니다. 실제로 머리를 열어보고 관리 메뉴를 끝까지 뒤져서 "없다"를 확인한 건 사람이 해야 했어요. 일반적으로 맞는 답과 여기서 되는 답은 다릅니다.
둘. 3이라는 숫자를 답으로 읽을 뻔했습니다. canonical 을 세었더니 3건이 나왔고, 거기서 멈췄으면 "있다"가 됐을 겁니다. 열어보니 셋 다 공유 버튼이었고, 정작 필요한 건 0건이었어요. 세는 건 정확한데, 세어진 게 무엇인지는 세기로 안 나옵니다.
셋. 손으로 280번 하면 되는 일을 안 하기로 정한 것. 할 수 있느냐만 보면 할 수 있는 일이었습니다. 뭘 파는 일인지를 보고 나서야 안 할 일이 됐어요.
남는 이야기
이번 편은 한 문장으로 줄면 이렇습니다.
도구가 없으면 문제를 다시 정의한다. 중복을 표시할 수 없으면 중복을 만들지 않는다.
처음엔 이게 타협처럼 보였어요. 정석대로 못 하니까 어쩔 수 없이 돌아가는 길로 갔다고요. 그런데 다 하고 나서 보니 돌아간 길이 더 짧았습니다. canonical 은 이미 겹친 걸 사후에 정리하는 반창고고, 채널마다 다른 걸 두는 건 겹치지 않게 앞에서 막는 거니까요. 반창고가 없어서 상처를 안 만드는 쪽으로 간 셈인데, 그게 원래 나은 겁니다.
그리고 하나 더요. 제 사이트 296장에 canonical 이 다 박혀 있는 건 제가 부지런해서가 아니라 거기가 제 코드라서입니다. 남의 집에 세 들어 사는 쪽에서는 그 한 줄을 못 넣어요. 대신 그 집에는 이웃이 있고 협찬이 오죠. 어느 쪽이 낫다는 얘기가 아니라, 집을 갖는다는 게 화면 예쁘게 만드는 일이 아니라 이런 한 줄을 내가 정할 수 있느냐의 문제더라는 겁니다. 도메인 값 만 원짜리로 산 게 실은 그거였어요.
#중복콘텐츠 #canonical #캐노니컬 #원본콘텐츠 #네이버블로그 #네이버블로그이관 #검색최적화 #SEO #구글색인 #서치콘솔 #검색허용 #robots #메타태그 #개인홈페이지 #홈페이지만들기 #victorhouse #클라우드플레어 #CloudflarePages #정적사이트 #블로그운영 #블로그수익화 #협찬리뷰 #검색유입 #파이썬자동화 #자동화 #AI코딩 #클로드 #바이브코딩 #개발자아닌사람 #사이드프로젝트