페이지는 기본 내보내기 컴포넌트야
page.tsx는 기본 내보내기로 React 컴포넌트를 제공해. 별도 지시가 없으면 서버 컴포넌트이므로 함수를 async로 만들고 그 자리에서 데이터를 기다릴 수 있어. 프레임워크가 페이지에 주는 라우팅 값은 params와 searchParams 두 가지야.
params에는[slug]처럼 폴더 이름에서 잡은 동적 구간이 들어와.searchParams에는 URL의 질의 문자열이 들어와.
Next.js 15부터 둘 다 Promise야
14에서 15로 넘어오며 가장 놓치기 쉬운 변경이야. 서버 페이지에서는 await params와 await searchParams처럼 기다린 뒤 값을 꺼내야 해. 클라이언트 컴포넌트에서 Promise를 받았다면 React.use(params)로 풀어. Promise로 감싼 덕분에 프레임워크는 경로 값이 준비되는 동안 다른 렌더링 작업을 먼저 시작할 수 있어.
문자열 경로에서 타입을 얻을 수도 있어
Next.js가 제공하는 PageProps<'/blog/[slug]'> 같은 도우미를 쓰면 실제 라우트 문자열을 바탕으로 params 타입을 만들 수 있어. 경로 이름을 바꿨는데 수동 타입만 옛 모양으로 남는 실수를 줄여 주지. 버전이 다른 예제를 가져왔다면 동기 객체처럼 바로 구조 분해하고 있지 않은지부터 확인해.
페이지가 받는 params와 searchParams는 외부 입력이야. Promise를 기다린 뒤 schema나 허용 목록으로 값을 검증하고, 존재하지 않는 자원은 notFound()로 끝내. 타입 도우미는 키 이름의 실수를 잡지만 실제 URL에 들어온 값의 유효성까지 증명하지는 않아.
질의 문자열을 읽는다는 이유로 모든 로직을 페이지 함수에 몰 필요는 없어. 페이지는 값을 해석해 도메인 컴포넌트에 넘기고, 정렬·필터 같은 규칙은 테스트 가능한 순수 함수로 빼. 프레임워크가 주입한 값과 제품 규칙의 경계가 분명해야 경로를 바꿔도 로직이 남아. 동적 값과 질의 문자열을 함께 쓰는 페이지에 정상 경로, 빠진 구간, 반복된 질의 키, 허용 범위 밖 값을 보내 봐. await를 빼면 타입과 실행이 어떻게 실패하는지 확인하고, 폴더를 [slug]에서 [postId]로 바꿨을 때 PageProps 타입도 따라오는지 봐. 404와 검증 오류가 서로 다른 응답을 만드는지도 확인해.