pages/ 안에 컴포넌트를 두면 안 되는 이유

Pages Router File Convention vs App Router Colocation

Next.jsPages RouterApp RouterColocation

난이도: ★★☆☆☆
연관 노트: SSG에서 ?page=2가 동작하지 않는 이유


핵심 요약

  1. Pages Router는 pages/ 안의 모든 파일을 URL 라우트로 인식한다.
  2. 컴포넌트 파일을 pages/blog/Button.tsx에 두면 /blog/Button 라우트가 의도치 않게 생겨버린다.
  3. App Router는 page.js 파일명만 라우트로 처리 — 같은 폴더에 아무 파일이나 둬도 안전하다 (Colocation).

왜 헷갈렸나

App Router처럼 Pages Router도 폴더 안에 컴포넌트를 같이 두면 되는 줄 알았음.
pages/ 폴더가 단순히 “페이지 관련 파일들을 모아두는 곳”이라고 생각했는데, 실제로는 파일 자체가 라우트 정의다.


메커니즘

Pages Router — 파일명 = URL 경로

pages/
├── blog/
│   ├── index.js     → /blog         (의도한 라우트)
│   └── Button.tsx   → /blog/Button  (의도치 않은 빈 라우트 생성!)
└── about.js         → /about

App Router — page.js 파일명만 라우트

app/
└── blog/
    ├── page.js      → /blog         (라우트)
    ├── Button.tsx   →               (라우트 아님, 안전)
    ├── styles.css   →               (라우트 아님, 안전)
    └── blog.test.js →               (라우트 아님, 안전)

핵심 차이:

Pages Router:  파일 경로 → URL   (파일이 라우트를 정의)
App Router:    폴더 경로 → URL   (page.js 있을 때만 라우트 활성화)

해결 패턴

Pages Router에서 컴포넌트 격리 (일반적 방법)

project/
├── pages/
│   └── blog/
│       └── index.tsx     ← 라우트만
├── components/
│   └── blog/
│       └── Button.tsx    ← 컴포넌트는 pages/ 밖에
└── hooks/
    └── useBlogData.ts

Pages Router에서 Colocation 우회 (pageExtensions 설정)

// next.config.js
module.exports = {
  pageExtensions: ['page.tsx', 'page.ts'],
}
// pages/blog/index.page.tsx → /blog       (라우트)
// pages/blog/Button.tsx     → 라우트 아님 (무시)

팀 전체가 컨벤션을 강제해야 해서 실무에서 거의 안 씀.


다음에 이 상황을 만나면

Pages Router 프로젝트에 컴포넌트 추가할 때:

  • 파일 위치가 pages/ 안인지 확인
  • pages/ 안이면 components/ 등 외부로 이동
  • App Router라면 page.js만 피하면 어디든 OK

커넥팅 닷

← 선행 개념 (이걸 알아야 이해된다)

  • SSG에서 ?page=2가 동작하지 않는 이유 — “URL = 파일 경로”라는 Next.js Pages Router의 핵심 규칙을 공유한다
  • 파일 시스템 기반 라우팅(File System Routing) — URL과 파일 구조를 1:1 매핑하는 패러다임. 이 규칙을 이해해야 “왜 파일이 라우트가 되는가”가 납득된다

→ 확장 개념 (여기서 더 나아가면)

  • Route Groups (folderName) — App Router에서 URL에 영향 없이 파일을 논리적으로 묶는 패턴. Colocation의 완성형
  • Private Folders _folderName — App Router에서 _ prefix로 라우팅 시스템에서 폴더를 완전히 제외하는 방법

↔ 같은 원리가 적용되는 곳


참고