Next.js
개인 프로젝트의 slug 버그를 빠르게 찾는 법
Next.js에서 slug 기반 라우팅이 제대로 동작하지 않을 때 원인을 찾는 체계적인 접근법.
개인 프로젝트에서 [slug].tsx 같은 동적 라우팅을 쓰면, slug가 제대로 인식되지 않는 버그가 생길 수 있다. 이런 버그는 빠르게 진단하지 못하면 시간을 낭비하게 된다.
먼저 URL을 명확히 한다
실제로 접속한 URL이 뭔지 정확히 본다. 브라우저 주소창을 확인한다.
https://example.com/blog/my-post-slug
이 URL에서 slug가 뭔지 명시적으로 적는다:
- 경로:
/blog/my-post-slug - slug:
my-post-slug
파일 구조를 확인한다
Next.js의 라우팅은 파일 구조에 정확히 따른다. 파일이 제대로 있는지 확인한다.
app/
blog/
[slug]/
page.tsx
폴더명과 파일명이 정확해야 한다. [slug]는 반드시 대괄호 안에만 있어야 한다.
slug 값이 제대로 전달되는지 서버에서 본다
라우트 핸들러에서 직접 slug를 출력해본다:
// app/blog/[slug]/page.tsx
export default function Page({ params }: { params: { slug: string } }) {
console.log('slug:', params.slug)
return <div>Slug: {params.slug}</div>
}
이제 페이지에 접속했을 때 slug가 정확히 출력되는지 본다.
정적 생성을 쓴다면 generateStaticParams를 확인한다
SSG(Static Site Generation)를 쓰고 있다면:
export async function generateStaticParams() {
const posts = await getPosts()
return posts.map(post => ({
slug: post.slug
}))
}
この함수가 반환하는 slug 목록이 실제 게시물의 slug와 일치하는지 확인한다.
데이터베이스에서 slug로 조회한다
slug가 맞게 전달되는데 데이터를 못 찾는다면, 조회 로직이 잘못됐을 수 있다.
const post = await db.posts.findUnique({
where: { slug: params.slug }
})
데이터베이스에 이 slug가 정말 존재하는지 확인한다:
# 데이터베이스 쿼리
SELECT * FROM posts WHERE slug = 'my-post-slug'
slug의 대소문자를 확인한다
URL에는 my-post-slug인데, 데이터베이스에는 My-Post-Slug로 저장돼있을 수 있다.
const post = await db.posts.findUnique({
where: {
slug: params.slug.toLowerCase() // 소문자로 통일
}
})
또는 데이터베이스에서 저장할 때부터 소문자로 정규화한다.
URL 인코딩을 고려한다
slug에 특수문자(한글, 공백 등)가 있으면 URL 인코딩된다.
https://example.com/blog/%ED%95%9C%EA%B8%80%EC%A0%9C%EB%AA%A9
이 경우 params.slug는 자동으로 디코딩되어야 하지만, 확인해본다:
console.log('encoded:', params.slug)
console.log('decoded:', decodeURIComponent(params.slug))
기본값 페이지를 만든다
slug가 일치하는 데이터가 없을 때를 대비해서:
if (!post) {
return notFound() // 404 페이지
}
NotFound 컴포넌트를 정의하면 사용자가 혼동하지 않는다.
브라우저 캐시를 비운다
Next.js는 개발 중에도 캐싱을 할 수 있다.
rm -rf .next
npm run dev
.next 폴더를 지운 후 다시 실행한다.
결론
slug 버그는 보통 파일 구조, 조회 로직, 혹은 대소문자 불일치에서 비롯된다. URL을 명확히 하고, 파일 구조를 확인하고, 실제 데이터와 비교하면 대부분 찾을 수 있다.