메인 페이지 money 섹션 추천글 중복 노출 버그 수정
목차
메인 페이지에서 같은 글이 두 번 나오는 걸 발견했다.
money 섹션의 메인 글(featured post)이 있고, 그 아래 카드 리스트에서 또 같은 글이 노출되고 있었다. 처음엔 "그냥 좀 어색한 거 아닌가" 싶었는데, 직접 화면을 보니 명백한 UX 버그였다. 같은 콘텐츠가 두 번 보이면 페이지 전체의 신뢰도가 떨어진다. 사용자 입장에서 "이 사이트 제대로 만든 거 맞아?" 하는 느낌을 줄 수 있는 작은 디테일이다.
왜 이런 중복이 생겼나
이런 패턴은 콘텐츠 목록 쿼리를 짤 때 자주 만나는 구조적 문제다. featured/메인 글을 별도로 뽑아서 상단에 고정 노출하고, 그 아래에 전체 글 목록을 카드 형태로 뿌리는 레이아웃이 있다. 이 두 쿼리가 각자 독립적으로 동작하면 당연히 featured 글이 목록에도 포함된다.
db.ts에서 글 목록을 가져오는 함수에 excludeSlugs 옵션을 추가하는 방식으로 해결했다. slug 배열을 받아서 쿼리 시점에 필터링하는 구조다.
// before
export function getPosts(category: string) {
return allPosts.filter(p => p.category === category);
}
// after
export function getPosts(category: string, excludeSlugs: string[] = []) {
return allPosts.filter(
p => p.category === category && !excludeSlugs.includes(p.slug)
);
}
그리고 index.astro에서 featured 글의 slug를 추출한 뒤, 카드 목록 쿼리 호출 시 넘겨주는 식으로 연결했다.
| 파일 | 역할 | 변경 내용 |
|---|---|---|
src/lib/db.ts |
콘텐츠 쿼리 레이어 | excludeSlugs 파라미터 추가 |
src/pages/index.astro |
메인 페이지 렌더링 | featured slug 추출 후 getPosts 에 전달 |
excludeSlugs 방식의 트레이드오프
다른 방법도 있었다. 목록에서 index 0번만 잘라내거나, 카드 렌더링 시점에 slug 비교로 skip하거나. 근데 이 두 방법 모두 데이터 레이어가 아닌 뷰 레이어에서 처리한다는 점이 마음에 안 들었다.
- 뷰에서 slice/filter: 빠르게 고칠 수 있지만, "어떤 글이 featured인지"라는 로직이 렌더링 코드에 박힌다. 나중에 featured 글이 복수가 되거나, 다른 페이지에서도 같은 로직이 필요해지면 중복이 생긴다.
- excludeSlugs를 db 레이어에: 쿼리 시점에 제거하니 카드 목록 자체가 처음부터 깨끗하다. 호출부가 의도를 명시적으로 드러낸다. 재사용성도 높다.
이런 작은 설계 결정이 쌓이면 나중에 코드 읽는 사람 입장에서 맥락을 파악하는 속도가 달라진다. 특히 팀이 있는 상황에서 "왜 이렇게 됐지?"를 추적하는 비용을 줄이는 게 총괄 입장에선 계속 신경 쓰는 부분이다.
회고
사실 이런 버그는 초기 구조를 잡을 때 featured + 목록 분리 설계를 좀 더 꼼꼼히 했으면 안 생길 수 있었다. 근데 솔직히 빠르게 만들다 보면 이런 케이스는 나중에 발견되는 경우가 많다. 중요한 건 발견했을 때 뷰에서 임시 땜빵하지 않고, 데이터 레이어에서 제대로 처리하는 결정을 하는 것.
excludeSlugs는 money 카테고리에만 쓰이고 있지만, 파라미터 자체는 범용이다. 다른 카테고리에서 비슷한 패턴이 생기면 그대로 재사용할 수 있다. 작은 수정이지만 확장 가능성을 열어두고 고친 게 잘한 선택이었다고 생각한다.
끝.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.