header_logo

COLDSURF BETA

#Encoding

#Slug

#DICE

#SEO

Written by Paul
최근 진행 중인 사이드 프로젝트에서 슬러그(slug)를 다듬는 작업을 하게 되었습니다. 처음엔 단순하게 생각했습니다. 특수문자는 인코딩하고, 공백은 대시(-)로 치환하면 끝날 줄 알았죠.
제가 만들고 있는 COLDSURF는 Kopis의 공연 API를 활용해 공연 티켓 정보를 모아 보여주는 서비스입니다. 공연 도메인 특성상 핵심 요소는 “공연 제목”, “공연 날짜”, “공연 장소” 등인데, 그중에서도 문제가 되었던 건 바로 “공연 제목을 기반으로 생성되는 slug”였습니다.

문제의 시작 – “#” 문자

Kopis API를 통해 수신되는 공연 제목에는 종종 회차를 나타내는 #1, #2 등의 문자가 포함되어 있습니다. 그러나 # 문자는 URL에서 Fragment Identifier로 해석되기 때문에, Next.js와 같은 SPA 구조에서는 /event/[slug]로 라우팅할 때 # 이후의 값이 잘려 나가고 맙니다.
예를 들어,
  • 공연 제목: 명동에서 벌어지는 재밌는 공연 #1
  • slugify 결과: 명동에서-벌어지는-재밌는-공연-#1
이 경우 사용자가 해당 링크를 통해 들어오면, Next.js에서는 params.slug 값으로 명동에서-벌어지는-재밌는-공연-까지만 인식하게 되고, 결국 404 페이지로 이동하게 됩니다.

첫 번째 해결책 – 인코딩

처음에는 encodeURIComponent로 모든 슬러그를 인코딩해 sitemap.xml에 반영하면 해결될 줄 알았습니다.
그러나 여기엔 또 다른 문제가 있었습니다.
  • 기존 DB에는 여전히 #이 포함된 slug가 저장되어 있어, 인코딩된 URL과 불일치함
  • 클라이언트에서 매번 decoding 처리를 해줘야 하고, 이 과정이 꼬일 수 있음
  • 이미 생성된 sitemap이나 공유된 링크와의 호환성 문제가 생김
즉, 새로운 방식과 기존 데이터 간의 충돌이 발생하게 된 것이죠.

전환점 – “#” 자체가 문제였다

이러한 시행착오 끝에 결국 깨달은 점은 단순했습니다.
”#“은 URL 슬러그로 사용할 수 없는 문자다.
브라우저와 서버의 URL 해석 방식이 다르고, SEO에서도 오히려 문제가 된다면 아예 제거하는 것이 맞다.

최종 해결책 – slugify 전처리

이후부터는 슬러그 생성 시 모든 특수문자를 명시적으로 치환하거나 제거하는 방향으로 정책을 변경했습니다. 예를 들어:
또한 기존에는 공연 제목만 slug로 사용했다면, 개선 후에는 SEO를 위해 날짜, 지역, 공연장 등의 정보를 조합하여 더 풍부한 슬러그를 생성했습니다.
예시:
제10회-대한민국장애인국제무용제-kiada-소극장-14th-aug-아르코예술극장-서울특별시-티켓

경험에서 얻은 교훈

이 경험을 통해 두 가지 중요한 교훈을 얻게 되었습니다.

1. 기본기의 중요성

웹에서 #이 어떤 의미를 가지는지 처음부터 명확히 이해했다면, 애초에 이런 구조적 문제를 만들지 않았을 것입니다. 결국 모든 오류의 뿌리는 기초 개념의 미비에서 비롯되었죠.

2. 개발은 기지다

slug에 날짜, 지역, 공연장 정보를 포함하는 방식은 DICE 서비스의 구조에서 착안한 것입니다. 개발은 기술만큼이나 기지가 중요한 분야임을 다시금 깨달았습니다. 잘 참고하고 잘 응용하는 것, 그것이 실력의 또 다른 이름이라 생각합니다.

이 글이 slug 처리나 SEO 개선을 고민하고 있는 분들께 도움이 되었기를 바랍니다. 작은 시행착오에서 배우는 인사이트가 가장 실용적인 법이니까요.

© 2025 COLDSURF, Inc.

Privacy Policy

Terms of Service

Products