상세문의 아이콘 상세문의
간편문의 아이콘 × 간편문의
canonical·트레일링 슬래시 디버깅 실록 · 2026

canonical 제대로 넣었는데
중복 페이지가 안 사라지는 이유

같은 글이 슬래시 있는 주소·없는 주소 둘 다로 열렸습니다.
대표 주소(canonical)가 방문한 주소를 그대로 가리키는 구조라, 링크를 섞어 거는 순간 같은 글이 둘로 갈릴 수 있는 상태였습니다.

홍은표 · 넥스트티 대표 · SEO/GEO 컨설턴트 | 작성 2026-06-05

DEFINITION · 한 문장 정의

사람 눈엔 /seo/seo/ 가 같은 페이지지만, 구글은 글자가 다른 두 주소로 볼 수 있습니다. 이때 “이 글의 진짜 주소는 이거예요”라고 검색엔진에 알려 주는 표식이 canonical(대표 주소)입니다. 그런데 우리 canonical은 방문한 주소를 그대로 가리키는 구조라 — 어떤 형태로 링크를 거느냐가 곧 대표 주소를 정합니다.

1분 요약 · KEY TAKEAWAYS

  • 같은 글이 /seo/what-is-seo/seo/what-is-seo/ 두 주소로 다 열렸습니다(둘 다 200).
  • canonical이 방문 주소를 자기참조해서, 링크를 두 형태로 섞어 걸면 같은 글의 대표 주소가 둘로 갈립니다 — 중복 콘텐츠 신호.
  • 범인은 한 페이지가 아니라 헤더·푸터가 공유하는 공통 메뉴 한 곳 — 어긋난 형태가 사이트 전체 링크에 동시에 번져 있었습니다.
  • 판별은 단순합니다 — 슬래시 없이 요청해서 301이면 디렉터리(슬래시 O), 200이면 파일(슬래시 X).
  • 링크·canonical·사이트맵을 한 형태로 통일 + 메뉴↔사이트맵 대조를 점검으로. 관측된 건 ‘형태 일치’까지 — 순위·트래픽 변화는 단정하지 않습니다.

THE PROBLEM

왜 같은 글이 두 주소로 잡혔나

주소 끝에 슬래시(/)가 붙고 안 붙고는 사소해 보입니다. 사람 눈엔 /seo/what-is-seo/seo/what-is-seo/ 나 같은 글이죠. 그런데 검색엔진은 글자가 다른 두 주소를 서로 다른 페이지로 볼 수 있습니다. 둘 다 똑같은 내용을 열어 주면, “같은 글이 두 군데 있다”처럼 읽힐 수 있습니다.

문제를 키운 건 우리 쪽 구조였습니다. 우리 사이트의 대표 주소(canonical) 태그는 방문한 주소를 그대로 가리킵니다. 슬래시 없는 주소로 들어오면 대표 주소도 슬래시 없이, 슬래시 붙은 주소로 들어오면 대표 주소도 슬래시 붙은 채로 적힙니다. 즉 “어떤 형태로 링크를 걸었느냐”가 곧 그 글의 대표 주소를 정합니다. 그러니 내부 링크가 두 형태로 섞이면, 같은 글의 대표 주소가 두 개로 갈라지는 셈입니다.

스키마를 잘못 넣어 또렷하게 틀린 신호를 줬던 지난 구조화 데이터 실록과 결이 같습니다. 이번엔 주소 한 글자가 같은 일을 합니다 — 눈에 잘 안 보이는데, 기계에는 또렷하게 갈라져 보이는 신호죠.

이 글은 그 갈라짐을 어떻게 발견하고, 어떻게 판별하고, 사이트 전체 링크를 어떻게 한 형태로 모았는지를 그대로 적은 현장 기록입니다. 일반론이 아니라, 우리가 실제로 겪고 고친 일입니다(2026년 5월).

FIELD LOG · 2026년 5월

무슨 일이 있었나 — 둘 다 열렸다

내부 링크를 점검하다 한 가지가 눈에 걸렸습니다. 같은 글인데 어떤 메뉴는 슬래시를 붙여, 어떤 본문 링크는 슬래시 없이 걸려 있었습니다. 직접 두 주소를 다 두드려 보니 — 둘 다 정상(200)으로 열렸습니다. 하나가 막혀 있으면 차라리 문제가 안 됩니다. 둘 다 열려서 문제였습니다.

더 신경 쓰였던 건 범위였습니다. 단발 실수 한두 개가 아니라, 헤더와 푸터가 함께 쓰는 공통 메뉴 한 곳에서 형태가 어긋나 있었습니다. 그 메뉴는 사이트 거의 모든 페이지에 똑같이 박히니까, 한 곳의 불일치가 사이트 전체에 동시에 번진 셈이었습니다(반대로 말하면, 한 곳만 고치면 전체가 같이 정리된다는 뜻이기도 했습니다).

WIREFRAME · 한 글, 두 주소

주소 A · 일부 메뉴/seo/what-is-seo
→ 200 OK
주소 B · 다른 링크/seo/what-is-seo/
→ 200 OK
▼  둘 다 똑같은 글을 연다
canonical = 방문한 주소 그대로
▼  그래서 대표 주소가…
A로 들어오면canonical = …/what-is-seo
B로 들어오면canonical = …/what-is-seo/
🤖 기계가 보기엔: 대표 주소가 둘 — 같은 글이 두 페이지로 갈릴 수 있음 ⚠

WHY IT MATTERS · 중복 콘텐츠

한 글의 평가가 둘로 쪼개질 수 있다

검색엔진은 같은 내용이 여러 주소에 있으면 그중 하나를 대표로 골라 묶으려 합니다(이걸 정규화·canonicalization이라 부릅니다). 그런데 우리가 거는 링크와 사이트맵이 두 형태로 갈려 있으면, “대표가 누구인지”에 대해 우리가 서로 다른 신호를 동시에 보내는 셈입니다. 그러면 한 글이 받아야 할 평가가 두 주소로 나뉠 수 있습니다. canonical은 명령이 아니라 힌트라, 신호가 엇갈리면 우리 뜻과 다르게 묶일 수도 있습니다.

섞여 있을 때 위험

1같은 글을 두 형태로 링크(슬래시 O / X)
2canonical이 방문 주소를 따라 둘로 적힘
3사이트맵에도 두 형태가 섞여 신호가 엇갈림
결과: 한 글의 평가가 둘로 갈릴 위험 ⚠

한 형태로 모으면 안전

1한 글 = 한 형태(예: 슬래시 X)로 통일
2canonical도 그 한 형태만 가리킴
3링크·canonical·사이트맵이 같은 곳을 봄
결과: 하나의 대표 주소로 또렷하게 ✓
// 우리 canonical 은 "방문한 주소"를 그대로 가리킨다 (자기참조)
<link rel="canonical" href="{사이트}{지금 요청한 경로}">

// 그래서 같은 글이라도 들어온 형태에 따라…
/seo/what-is-seo    canonical = /seo/what-is-seo
/seo/what-is-seo/   canonical = /seo/what-is-seo/   // 다른 대표 주소!
// 정리: 한 글은 한 형태로만 링크 → canonical 도 하나로 모인다
// 내부 링크·본문·사이트맵 전부 같은 형태:
/seo/what-is-seo          // 말단 콘텐츠(파일) → 슬래시 X
/seo/                     // 섹션 루트(디렉터리) → 슬래시 O
/seo/portfolio/           // 목록·페이징 → 슬래시 O

덧붙이면, AI 검색도 결국 URL 단위로 읽습니다. 같은 내용을 여러 주소가 나눠 가지면, AI가 대표로 인용할 신호와 대표성도 분산될 수 있습니다 — SEO의 중복 문제가 그대로 GEO(생성형 엔진 최적화)의 인용 문제로 이어지는 셈입니다.

HOW WE FOUND IT

어떻게 찾았나 — 슬래시 없이 두드려 본다

형태를 정하는 기준이 필요했습니다. 취향으로 정하면 또 흔들리니까요. 그래서 주소를 슬래시 없이 요청해 응답 코드를 보는 단순한 규칙을 세웠습니다. 슬래시 붙은 쪽으로 넘겨주면(301) 그 페이지는 슬래시를 붙이는 게 맞고, 그대로 열리면(200) 슬래시 없는 형태로 통일합니다. 서버가 이미 정해 둔 자연스러운 형태를 그대로 따르는 셈입니다.

WIREFRAME · 점검 파이프라인

1 · 모으기내부 링크 전부 수집(메뉴·본문·사이트맵)
2 · 판별슬래시 없이 요청 → 301=슬래시O, 200=슬래시X
3 · 대조메뉴 링크가 사이트맵에도 같은 형태인지 비교
결과: 공통 메뉴의 말단 링크들이 슬래시 O/X 혼재 + 사이트맵에 두 형태 중복
// 의사코드 — 페이지를 눈으로 도는 게 아니라 "형태를 판별·대조"
for url in allInternalLinks:
  code = head(stripSlash(url))            // 슬래시 빼고 요청
  form = (code == 301) ? withSlash(url) : noSlash(url)
  enforce(form)                           // 링크·canonical·sitemap 모두 이 형태로

// 마지막: 메뉴 ↔ 사이트맵 자동 대조
assert( menuLinks ⊆ sitemapLocs )       // 형태까지 같아야 통과

핵심은 “느낌으로 통일”이 아니라 “서버 응답으로 판별”한다는 점, 그리고 한 번 고치고 끝이 아니라 메뉴↔사이트맵 대조를 점검으로 남겨 다음에 또 어긋나면 바로 걸리게 한다는 점입니다.

3-SECOND CHECK

지금 내 사이트로 바로 해보는 점검

아무 글 하나를 골라 슬래시를 붙였다 뗐다 하며 다섯 가지만 보면 됩니다.

/글주소/글주소/ 가 둘 다 열리나? — 둘 다 200이면 통일 대상입니다.
둘 중 하나가 301로 다른 쪽으로 넘어가나? — 넘어가면 서버가 ‘진짜 주소’를 이미 정한 것입니다.
canonical 주소가 그 ‘최종 도착 주소’와 한 글자도 안 틀리고 같나? — 슬래시 하나라도 다르면 신호가 엇갈립니다.
사이트맵(sitemap.xml)의 주소도 같은 형태인가? — 사이트맵이 다른 형태를 제출하면 또 갈립니다.
내부 링크(메뉴·본문·배너)가 전부 한 형태로 통일됐나? — 한 곳만 어긋나도 그 형태가 따로 인식될 수 있습니다.

다섯 줄 중 하나라도 ‘아니오’면, 같은 글이 두 주소로 갈리고 있을 수 있습니다.

THE FIX

어떻게 고쳤나 — 세 가지 정리

FIX 01

형태 기준을 응답 코드로 못 박기

취향이 아니라 규칙으로 — 슬래시 없이 요청해 301이면 슬래시 붙는 형태, 200이면 슬래시 없는 형태로 정했습니다. 섹션 루트·목록(/seo/·/seo/portfolio/)은 슬래시 O, 말단 콘텐츠(/seo/what-is-seo)는 슬래시 X로 갈렸습니다.

FIX 02

링크를 “한 곳”에서 통일

페이지마다 일일이 고치는 대신, 헤더·푸터가 공유하는 공통 메뉴 한 곳을 바로잡았습니다. 거기서 형태를 맞추니 사이트 전체 링크가 같이 정리됐습니다. 본문·크로스셀·구조화 데이터 속 주소도 같은 형태로 맞췄습니다.

FIX 03

사이트맵도 같은 형태 + 대조를 자동화

사이트맵의 주소도 같은 규칙으로 출력하고, 두 형태가 중복 등록되던 부분을 정리했습니다. 그리고 메뉴의 링크가 사이트맵에 같은 형태로 들어 있는지 대조하는 점검을 남겨, 다음에 새 페이지가 어긋나면 바로 드러나게 했습니다.

한 걸음 더 — 가장 강한 방법은 301
교과서적으로 가장 깔끔한 건 한 형태만 200으로 열고 나머지는 301로 넘기는 것입니다(짝퉁 주소로 들어와도 진짜 주소로 자동 이동). 우리 사이트의 디렉터리 주소(/seo/ 같은 섹션 루트)는 서버가 이미 그렇게 자동으로 넘깁니다. 다만 말단 글 주소는 둘 다 200으로 열리는 구조라, 우리는 링크를 한 형태로 모으고 canonical이 자기 주소를 가리키게 해 신호를 일치시켰습니다. 서버에서 한쪽을 301로 강제하는 것도 다음 단계 옵션입니다 — 사이트 구조에 따라 고르면 됩니다.

관측된 결과 — 통일 후 링크·canonical·사이트맵이 한 형태로 일치하게 됐습니다. 다만 여기까지가 관측된 사실이고, 이걸로 순위가 올랐다거나 트래픽이 늘었다고는 말하지 않습니다. 우리가 본 것만 책임집니다 — 측정의 경계를 지킵니다.

HOW WE DEBUG · 넥스트티 방식

넥스트티는 “링크를 걸었는지”가 아니라 “한 곳을 가리키는지”를 봅니다

많은 점검이 “깨진 링크가 있나(404)”에서 끝납니다. 그런데 더 조용히 비용을 키우는 건, 안 깨졌는데 두 주소로 다 열리는 경우입니다. 둘 다 200이라 점검에선 멀쩡해 보이는데, 정작 대표 주소가 둘로 갈리고 있는 상태죠. 그래서 우리는 “열리나”가 아니라 “같은 글이 한 곳을 가리키나”를 봅니다.

그리고 한 페이지가 아니라 사이트 전체의 링크 형태를 한꺼번에 봅니다. 1편(구조화 데이터)에서 같은 대상을 같은 이름으로 쓰는지를 봤듯, 이번엔 같은 글을 같은 형태로 가리키는지를 한 번에 맞춥니다. 페이지 한 장의 실수보다, 공통 틀을 타고 전체에 번지는 누적 오류가 더 위험하다고 보기 때문입니다.

현업에서 자주 보는 풍경

canonical 한 줄만 맞춘다고 끝나지 않습니다. 내부 링크는 슬래시 붙은 형태, 사이트맵은 슬래시 없는 형태, canonical은 또 다른 형태 — 이렇게 세 신호가 어긋나 있으면, 검색엔진은 어느 쪽이 대표인지 헷갈려 canonical을 무시하거나 인덱싱(검색 노출)을 미룰 수 있습니다. Search Console의 “중복 페이지”가 좀처럼 안 사라지는 흔한 이유가 이것입니다. 그래서 우리는 한 줄이 아니라, 링크·canonical·사이트맵 세 신호가 같은 형태인지를 함께 봅니다.

측정

‘열리나’가 아니라 ‘하나로 모이나’

둘 다 200이라 멀쩡해 보이는 중복을, 응답 코드와 대표 주소로 가려냅니다. 깨진 링크 점검만으론 안 잡힙니다.

규모

한 장씩이 아니라 한꺼번에

링크 형태를 사이트 전체에서 모아 판별합니다. 공통 메뉴 한 곳이 어긋나면 전체가 어긋나니, 한 곳에서 통일합니다.

정합

링크·canonical·사이트맵을 한 방향으로

세 신호가 같은 곳을 가리켜야 우리 뜻대로 묶입니다. 셋이 어긋나면 canonical 한 줄로는 정리되지 않습니다.

운영

한 번 점검이 아니라 점검을 남긴다

메뉴↔사이트맵 대조를 반복 가능한 점검으로 남겨, 페이지가 늘어도 새로 어긋난 형태가 바로 드러나게 합니다.

그래서 차이는 — 트레일링 슬래시는 ‘링크를 거는’ 문제가 아니라 ‘한 곳을 가리키게 하는’ 문제입니다. 링크는 누구나 겁니다. 같은 글이 한 주소로 모이게 맞추는 일은 측정 없이는 안 됩니다 — 그게 넥스트티가 하는 일입니다.

5 RULES · 재현 가능한 원칙

같은 실수를 막는 5가지 원칙

원칙
한 글 = 한 형태같은 글은 슬래시 O/X 중 한 형태로만 링크. 형태가 갈리면 대표 주소도 갈립니다.
형태는 응답 코드로 판별느낌이 아니라 규칙으로 — 슬래시 없이 요청해 301이면 슬래시 O, 200이면 슬래시 X.
링크는 한 곳에서 관리공통 메뉴를 한 곳에서 정의하면 한 번에 통일됩니다. 페이지마다 복붙하면 또 갈라집니다.
canonical·링크·사이트맵 일치세 신호가 같은 형태를 가리켜야 합니다. canonical 한 줄만 믿으면, 링크·사이트맵이 다른 말을 합니다.
대조를 점검으로 남기기한 번 고치고 끝이 아니라, 메뉴↔사이트맵 대조를 반복 점검으로. 새 페이지가 어긋나면 바로 잡힙니다.

COMMON MYTHS · 자주 보는 오해

트레일링 슬래시에 대해 자주 듣는 세 가지 오해

MYTH 01

"슬래시는 그냥 취향 차이다"

canonical이 방문 주소를 그대로 가리키는 구조라면, 형태가 곧 대표 주소입니다. 취향으로 섞으면 같은 글이 두 주소로 갈립니다 — 한 사이트 안에서 한 형태로 정해 두는 게 안전합니다.

MYTH 02

"둘 다 200으로 열리니 문제없다"

접근이 된다는 것과 한 주소로 합쳐진다는 것은 다릅니다. 오히려 둘 다 열려서 평가가 나뉠 수 있습니다. 깨진 링크(404)만 찾는 점검으론 이 조용한 중복이 안 잡힙니다.

MYTH 03

"rel=canonical 한 줄이면 다 정리된다"

canonical은 명령이 아니라 힌트입니다. 게다가 자기참조 구조면 링크·사이트맵이 어긋날 때 서로 다른 신호를 같이 보냅니다. 셋이 같은 형태를 가리켜야 비로소 한 방향이 됩니다.

FAQ

자주 묻는 질문

트레일링 슬래시(URL 끝 /)는 그냥 취향 차이 아닌가요?+
경우에 따라 다릅니다. 슬래시 있고 없고가 둘 다 같은 내용을 열어 준다면, 검색엔진은 이를 서로 다른 두 주소로 볼 수 있습니다. 특히 canonical(대표 주소) 태그가 방문한 주소를 그대로 가리키는 구조라면, 어떤 형태로 링크를 거느냐가 곧 대표 주소를 정합니다. 그래서 한 형태로 통일하는 편이 안전합니다.
슬래시 있는 주소와 없는 주소가 둘 다 200으로 열리면 문제인가요?+
둘 다 열린다는 점 자체가 위험 신호일 수 있습니다. 접근이 된다는 것과 한 주소로 합쳐진다는 것은 다릅니다. 같은 내용이 두 주소로 다 열리고, 내부 링크가 두 형태로 섞여 있으면 같은 글의 평가가 둘로 나뉠 수 있습니다. 한 형태로 모으는 것이 좋습니다.
어떤 페이지에 슬래시를 붙이고 어떤 페이지에 빼야 하나요?+
정답이 정해진 건 아니지만, 한 사이트 안에서 일관되면 됩니다. 한 가지 실무 기준은, 슬래시 없이 주소를 요청했을 때 응답 코드를 보는 것입니다. 301로 슬래시 붙은 주소로 넘어가면 그 페이지는 슬래시를 붙이는 게 자연스럽고, 그대로 200이면 슬래시 없는 형태로 통일하면 됩니다.
rel="canonical" 한 줄만 넣으면 중복은 정리되나요?+
한 줄로 끝나지 않습니다. canonical은 명령이 아니라 힌트입니다. 게다가 canonical이 방문 주소를 자기참조하는 구조라면, 링크와 사이트맵이 형태가 어긋날 때 서로 다른 신호를 동시에 보내게 됩니다. canonical·내부 링크·사이트맵이 같은 형태로 일치해야 신호가 한 방향을 가리킵니다.
중복 주소는 어떻게 한 번에 찾나요?+
페이지를 하나씩 여는 대신, 사이트의 내부 링크를 한데 모은 뒤 각 주소를 슬래시 없이 요청해 응답 코드로 형태를 정하고, 그 형태에 맞지 않게 걸린 링크를 추려 내면 됩니다. 마지막으로 메뉴의 링크가 사이트맵에도 같은 형태로 들어 있는지 대조하면 누락·불일치가 드러납니다.
슬래시를 통일하면 순위가 오르나요?+
단정하기 어렵습니다. 저희가 관측한 것은 링크·canonical·사이트맵이 한 형태로 일치하게 됐다는 사실까지입니다. 순위·트래픽 변화는 여러 요인이 얽혀 있어 인과로 단정하지 않습니다 — 관측과 추정을 구분하는 것이 정직한 측정입니다.

CONCLUSION

트레일링 슬래시는 ‘링크’가 아니라 ‘한 곳을 가리키는가’의 문제입니다.

둘 다 열린다고 안전한 게 아닙니다. 중요한 건 같은 글이 한 주소로 모이는가입니다. 링크·canonical·사이트맵이 같은 곳을 가리키게 맞추는 것 — 그게 이 글이 말하려던 전부입니다.

덧붙이자면, 이 글의 주소에도 끝에 슬래시가 없습니다(/seo/canonical-trailing-slash). 우리가 정한 규칙을 이 페이지부터 지킵니다.

DIAGNOSE · URL CONSISTENCY

우리 사이트의 주소는 한 곳을 가리키는가

넥스트티는 링크를 ‘걸었는지’로 판단하지 않습니다 — 같은 글이 한 주소로 모이는지, canonical·링크·사이트맵이 같은 방향을 보는지까지 확인합니다.
트레일링 슬래시 통일 · 자기참조 canonical 점검 · 메뉴↔사이트맵 대조부터 시작합니다.