✅ /product, /product/[id]
/product와 /product/[id] 페이지를 개발하며
갑자기 마주한 페이지 이동에 대한 고민을 메모해두려합니다.
예를 들어 상품 페이지에는 여러 카테고리가 있고,
선택된 카테고리에 해당하는 상품을 보여주는 구조라면
/product/[id]의 [id]는 카테고리 ID라고 볼 수 있겠죠.
그래서 저는 /product로 접근했을 때
가장 첫 카테고리의 ID로 리다이렉트 시켜주는 구조를 만들고 싶었습니다.
🔁 처음 시도한 방식: 내부에서 [id] 페이지를 호출
처음에는 아래와 같이 /product/page.tsx에서 /product/[id]/page.tsx를 직접 호출하도록 했습니다.
// product/page.tsx
import ProductPage from '@/app/[locale]/product/[id]/page';
export default async function Page() {
return <ProductPage />;
}
그 당시엔 "중복 코드가 없다"는 이유로 만족했지만,
나중에 보니…
- page.tsx는 보통 SSR용 진입점으로 사용중인데 컨벤션에 어긋남!
- /product/[id]라고 되어 있으니 ID가 필수인 경로인데, ID 없이 들어올 수 있다는 점에서 라우팅의 명확성이 떨어졌으며
- 가장 결정적으로는, 동일한 콘텐츠가 서로 다른 URL로 노출되면 SEO에 악영향을 미친다는 사실을 알게 되었습니다.
🔗 중복 콘텐츠 관련 SEO 가이드
🔀 리다이렉트로 리팩토링 (서버 사이드)
그래서 /product로 접근하면 가장 첫 카테고리 ID로 리다이렉트하는 구조로 바꾸었고,
Next.js의 서버 컴포넌트에서 redirect()를 사용해 처리했습니다.
// product/page.tsx
export default async function Page() {
const { i18n } = await getT();
const promotionCategories = await getCategories({ isPromotion: true });
if (!promotionCategories) {
return notFound();
}
redirect(`/${i18n.resolvedLanguage}/product/${promotionCategories[0].id}`);
}
그런데...
😫 화면 깜빡임이 생겼습니다...
❗ 문제 원인: 서버 컴포넌트의 redirect()는 깜빡임이 생길 수 있음
조사해보니 이건 Next.js App Router에서 알려진 이슈였습니다.
+) loading.tsx을 설정해봐도 loading이 보인 후에 똑같이 깜빡거림이 발생했습니다.
🛠️ 최종 해결 방향: /product/page.tsx는 제거
결국 /product/page.tsx는 아예 제거하고,
메뉴를 생성할 때부터 첫 번째 카테고리 ID로 URL을 고정하도록 변경했습니다.
// getNavigationMenu.ts
{
href: promotionsMenu[0].href, // 가장 첫 번째 카테고리로 연결
label: t('menu.promotions'),
children: promotionsMenu,
}
중복 호출이 우려되어 fetch에 next: { revalidate } 옵션을 넣어 캐싱 처리도 함께 적용했습니다.
🔗 Next.js fetch 캐싱 문서
💡 추후 고려할 수 있는 방법? canonical 설정
글을 작성하다 발견하게 되었는데 canonical 설정이 가능하니,
/product와 /product/[id]가 동일한 컴포넌트를 바라보게 하고
canonical 태그로 SEO 중복 문제를 해결하는 방식도 가능하지 않을까 생각했습니다..!
// generateMetadata.ts
export async function generateMetadata(...) {
return {
alternates: {
canonical: `https://example.com/product/${id}`,
},
};
}
✅ 정리
시도한 방식결과
/product에서 [id] 페이지 직접 호출 | ❌ SSR 구조와 어긋남, SEO 이슈 |
서버 사이드에서 redirect | ❌ 깜빡임 발생 |
클라이언트에서 router.replace | ✅ UX는 좋지만 SEO 중복 문제 발생 |
메뉴 구성 단계에서 첫 카테고리 ID로 URL 설정 | ✅ 가장 안정적인 방식으로 선택 |
🧩 결론
리다이렉트를 하는데 이렇게 많은 고민을 하게 될 줄은 몰랐습니다...🥹
그래도 오랜만에 이것 저것 알아보며 재미있었네요.
좋은 방향이 있다면 꼭 말씀 부탁드려요!
'개발 일지' 카테고리의 다른 글
[AWS] CloudFront + SSL + Route53 (0) | 2025.01.13 |
---|---|
[코딩테스트] Call Function with Custom Context (feat. this) (0) | 2024.08.22 |
SQL Injection 공격이 들어왔다 😵 (0) | 2024.08.14 |