Next.js 폴더 및 파일 규칙
이 페이지는 Next.js의 모든 폴더 및 파일 규칙에 대한 개요와 프로젝트 구성 권장사항을 제공합니다.
폴더 및 파일 규칙
최상위 폴더
최상위 폴더는 애플리케이션의 코드와 정적 자산을 구성하는 데 사용됩니다.
| 폴더 | 설명 |
|---|---|
| app | App Router |
| pages | Pages Router |
| public | 제공될 정적 자산 |
| src | 선택적 애플리케이션 소스 폴더 |
팀의 규모와 프로젝트 복잡도에 따라 적절한 구조를 선택하세요. 소규모 프로젝트는 app 폴더만 사용하고, 대규모 프로젝트는 src 폴더를 활용하여 설정 파일과 소스 코드를 분리하는 것이 좋습니다.
최상위 파일
최상위 파일은 애플리케이션 구성, 의존성 관리, 미들웨어 실행, 모니터링 도구 통합, 환경 변수 정의에 사용됩니다.
| 파일 | 설명 |
|---|---|
| next.config.js | Next.js 구성 파일 |
| package.json | 프로젝트 의존성 및 스크립트 |
| instrumentation.ts | OpenTelemetry 및 계측 파일 |
| middleware.ts | Next.js 요청 미들웨어 |
| .env | 환경 변수 |
| .env.local | 로컬 환경 변수 |
| .env.production | 프로덕션 환경 변수 |
| .env.development | 개발 환경 변수 |
| .eslintrc.json | ESLint 구성 파일 |
| .gitignore | Git에서 무시할 파일 및 폴더 |
| next-env.d.ts | Next.js용 TypeScript 선언 파일 |
| tsconfig.json | TypeScript 구성 파일 |
| jsconfig.json | JavaScript 구성 파일 |
환경별로 다른 설정이 필요한 경우, .env.local (로컬 개발), .env.production (프로덕션), .env.development (개발) 파일을 활용하세요. 민감한 정보는 반드시 .env.local에 저장하고 .gitignore에 포함시켜야 합니다.
라우팅 파일
| 파일 | 확장자 | 설명 |
|---|---|---|
| layout | .js .jsx .tsx | 레이아웃 |
| page | .js .jsx .tsx | 페이지 |
| loading | .js .jsx .tsx | 로딩 UI |
| not-found | .js .jsx .tsx | 404 UI |
| error | .js .jsx .tsx | 오류 UI |
| global-error | .js .jsx .tsx | 전역 오류 UI |
| route | .js .ts | API 엔드포인트 |
| template | .js .jsx .tsx | 재렌더링 레이아웃 |
| default | .js .jsx .tsx | 병렬 라우트 폴백 페이지 |
loading.tsx는 Suspense 경계를 자동으로 생성하여 로딩 상태를 처리합니다. error.tsx는 Error Boundary를 생성하여 오류를 우아하게 처리할 수 있습니다. 이러한 파일들을 적절히 활용하면 사용자 경험을 크게 향상시킬 수 있습니다.
중첩 라우트
| 폴더 구조 | 설명 |
|---|---|
| folder | 라우트 세그먼트 |
| folder/folder | 중첩 라우트 세그먼트 |
동적 라우트
| 폴더 구조 | 설명 |
|---|---|
| [folder] | 동적 라우트 세그먼트 |
| [...folder] | 모든 경로를 포함하는 라우트 세그먼트 |
| [[...folder]] | 선택적 모든 경로를 포함하는 라우트 세그먼트 |
- [id]: 블로그 포스트 상세 페이지 (/posts/123)
- [...slug]: 다단계 카테고리 (/category/electronics/phones/iphone)
- [[...slug]]: 선택적 다단계 경로 (/shop 또는 /shop/category/item)
라우트 그룹과 프라이빗 폴더
| 폴더 구조 | 설명 |
|---|---|
| (folder) | 라우팅에 영향을 주지 않고 라우트 그룹화 |
| _folder | 폴더와 모든 하위 세그먼트를 라우팅에서 제외 |
병렬 및 가로채기 라우트
| 폴더 구조 | 설명 |
|---|---|
| @folder | 명명된 슬롯 |
| (.)folder | 같은 레벨 가로채기 |
| (..)folder | 한 레벨 위 가로채기 |
| (..)(..)folder | 두 레벨 위 가로채기 |
| (...)folder | 루트에서 가로채기 |
대시보드에서 사이드바(@sidebar)와 메인 콘텐츠(@main)를 별도로 관리하거나, 모달 인터셉션을 통해 사용자 경험을 향상시킬 수 있습니다.
메타데이터 파일 규칙
앱 아이콘
| 파일 | 확장자 | 설명 |
|---|---|---|
| favicon | .ico | 파비콘 파일 |
| icon | .ico .jpg .jpeg .png .svg | 앱 아이콘 파일 |
| icon | .js .ts .tsx | 생성된 앱 아이콘 |
| apple-icon | .jpg .jpeg .png | 애플 앱 아이콘 파일 |
| apple-icon | .js .ts .tsx | 생성된 애플 앱 아이콘 |
Open Graph 및 Twitter 이미지
| 파일 | 확장자 | 설명 |
|---|---|---|
| opengraph-image | .jpg .jpeg .png .gif | Open Graph 이미지 파일 |
| opengraph-image | .js .ts .tsx | 생성된 Open Graph 이미지 |
| twitter-image | .jpg .jpeg .png .gif | Twitter 이미지 파일 |
| twitter-image | .js .ts .tsx | 생성된 Twitter 이미지 |
동적으로 생성되는 페이지에서는 .tsx 파일을 사용하여 콘텐츠에 맞는 Open Graph 이미지를 자동 생성할 수 있습니다. 이는 SEO와 소셜 미디어 공유에 매우 효과적입니다.
SEO
| 파일 | 확장자 | 설명 |
|---|---|---|
| sitemap | .xml | 사이트맵 파일 |
| sitemap | .js .ts | 생성된 사이트맵 |
| robots | .txt | Robots 파일 |
| robots | .js .ts | 생성된 Robots 파일 |
프로젝트 구성하기
Next.js는 프로젝트 파일을 어떻게 구성하고 배치할지에 대해 강제하지 않습니다. 하지만 프로젝트를 구성하는 데 도움이 되는 여러 기능을 제공합니다.
컴포넌트 계층구조
특수 파일에 정의된 컴포넌트는 특정 계층구조로 렌더링됩니다:
├── template.js
├── error.js (React error boundary)
├── loading.js (React suspense boundary)
├── not-found.js (React error boundary)
└── page.js 또는 중첩된 layout.js
컴포넌트는 중첩 라우트에서 재귀적으로 렌더링되므로, 라우트 세그먼트의 컴포넌트는 부모 세그먼트의 컴포넌트 내부에 중첩됩니다.
콜로케이션 (Colocation)
app 디렉터리에서 중첩된 폴더는 라우트 구조를 정의합니다. 각 폴더는 URL 경로의 해당 세그먼트에 매핑되는 라우트 세그먼트를 나타냅니다.
그러나 폴더를 통해 라우트 구조가 정의되더라도, 라우트 세그먼트에 page.js 또는 route.js 파일이 추가되기 전까지는 공개적으로 접근할 수 없습니다.
그리고 라우트가 공개적으로 접근 가능하게 되더라도, page.js 또는 route.js에서 반환된 내용만 클라이언트로 전송됩니다.
이는 프로젝트 파일들이 실수로 라우팅되지 않고 app 디렉터리의 라우트 세그먼트 내부에 안전하게 배치될 수 있음을 의미합니다.
app 내에서 프로젝트 파일을 배치할 수 있지만, 반드시 그래야 하는 것은 아닙니다. 원한다면 app 디렉터리 외부에 보관할 수 있습니다.
프라이빗 폴더
프라이빗 폴더는 폴더명 앞에 언더스코어를 붙여 생성할 수 있습니다: _folderName
이는 해당 폴더가 프라이빗 구현 세부사항이며 라우팅 시스템에서 고려되지 않아야 함을 나타내어, 폴더와 모든 하위 폴더를 라우팅에서 제외시킵니다.
컴포넌트 라이브러리, 유틸리티 함수, 테스트 파일 등을 _components, _utils, _tests 폴더에 정리하면 라우팅에서 제외되면서도 관련 라우트 근처에 배치할 수 있어 유지보수가 편해집니다.
app 디렉터리의 파일들은 기본적으로 안전하게 배치될 수 있으므로 콜로케이션을 위해 프라이빗 폴더가 반드시 필요한 것은 아닙니다. 하지만 다음과 같은 경우에 유용합니다:
- UI 로직과 라우팅 로직 분리
- 프로젝트와 Next.js 생태계 전반에 걸쳐 내부 파일을 일관되게 구성
- 코드 에디터에서 파일 정렬 및 그룹화
- 향후 Next.js 파일 규칙과의 잠재적 이름 충돌 방지
- 프레임워크 규칙은 아니지만, 프라이빗 폴더 외부의 파일들도 같은 언더스코어 패턴을 사용하여 "프라이빗"으로 표시하는 것을 고려할 수 있습니다.
- 폴더명 앞에 %5F(언더스코어의 URL 인코딩 형태)를 붙여 언더스코어로 시작하는 URL 세그먼트를 만들 수 있습니다: %5FfolderName.
- 프라이빗 폴더를 사용하지 않는다면, 예상치 못한 이름 충돌을 방지하기 위해 Next.js 특수 파일 규칙을 알아두는 것이 도움이 됩니다.
라우트 그룹
라우트 그룹은 폴더를 괄호로 감싸서 생성할 수 있습니다: (folderName)
이는 폴더가 조직적 목적이며 라우트의 URL 경로에 포함되지 않아야 함을 나타냅니다.
- (marketing): 마케팅 관련 페이지들
- (dashboard): 대시보드 관련 페이지들
- (auth): 인증 관련 페이지들
이렇게 그룹화하면 각 그룹마다 다른 레이아웃을 적용할 수 있고, 팀 단위로 작업할 때 코드를 효율적으로 관리할 수 있습니다.
라우트 그룹은 다음과 같은 용도로 유용합니다:
- 사이트 섹션, 의도 또는 팀별로 라우트 구성 (예: 마케팅 페이지, 관리자 페이지 등)
- 같은 라우트 세그먼트 레벨에서 중첩 레이아웃 활성화:
- 같은 세그먼트에서 여러 중첩 레이아웃 생성 (여러 루트 레이아웃 포함)
- 공통 세그먼트의 라우트 하위 집합에 레이아웃 추가
src 폴더
Next.js는 선택적 src 폴더 내부에 애플리케이션 코드(app 포함)를 저장하는 것을 지원합니다. 이는 대부분 프로젝트 루트에 있는 프로젝트 구성 파일들로부터 애플리케이션 코드를 분리합니다.
대규모 프로젝트에서는 src 폴더를 사용하여 소스 코드와 설정 파일을 명확히 분리하는 것이 좋습니다. 이는 프로젝트 구조를 더 깔끔하게 만들고 새로운 개발자가 프로젝트를 이해하기 쉽게 만듭니다.
프로젝트 구성 전략
다음 섹션에서는 일반적인 전략들의 고수준 개요를 나열합니다. 가장 간단한 요점은 여러분과 팀에게 맞는 전략을 선택하고 프로젝트 전반에 걸쳐 일관성을 유지하는 것입니다.
아래 예시에서 components와 lib 폴더는 일반화된 플레이스홀더로 사용되며, 이들의 명명은 특별한 프레임워크적 의미가 없습니다. 프로젝트에서는 ui, utils, hooks, styles 등 다른 폴더를 사용할 수 있습니다.
1. app 외부에 프로젝트 파일 저장
이 전략은 모든 애플리케이션 코드를 프로젝트 루트의 공유 폴더에 저장하고 app 디렉터리를 순수하게 라우팅 목적으로만 유지합니다.
2. app 내부의 최상위 폴더에 프로젝트 파일 저장
이 전략은 모든 애플리케이션 코드를 app 디렉터리 루트의 공유 폴더에 저장합니다.
3. 기능 또는 라우트별로 프로젝트 파일 분할
이 전략은 전역적으로 공유되는 애플리케이션 코드를 루트 app 디렉터리에 저장하고, 더 구체적인 애플리케이션 코드를 해당 코드를 사용하는 라우트 세그먼트로 분할합니다.
- 소규모 프로젝트: 전략 2번 추천 - 모든 코드를 app 내부에 정리
- 중규모 프로젝트: 전략 1번 추천 - 명확한 분리를 통한 관리
- 대규모 프로젝트: 전략 3번 추천 - 기능별 분할로 확장성 확보
URL 경로에 영향을 주지 않고 라우트 구성하기
URL에 영향을 주지 않고 라우트를 구성하려면, 관련 라우트를 함께 유지하는 그룹을 만드세요. 괄호 안의 폴더는 URL에서 생략됩니다 (예: (marketing) 또는 (shop)).
(marketing)과 (shop) 내부의 라우트가 같은 URL 계층구조를 공유하더라도, 각 그룹의 폴더 내부에 layout.js 파일을 추가하여 각 그룹마다 다른 레이아웃을 만들 수 있습니다.
특정 세그먼트를 레이아웃에 포함시키기
특정 라우트를 레이아웃에 포함시키려면, 새로운 라우트 그룹(예: (shop))을 만들고 같은 레이아웃을 공유하는 라우트들을 그룹으로 이동시키세요(예: account와 cart). 그룹 외부의 라우트는 레이아웃을 공유하지 않습니다(예: checkout).
특정 라우트에 로딩 스켈레톤 적용하기
loading.js 파일을 통해 특정 라우트에 로딩 스켈레톤을 적용하려면, 새로운 라우트 그룹(예: /(overview))을 만들고 해당 라우트 그룹 내부에 loading.tsx를 이동시키세요.
이제 loading.tsx 파일은 URL 경로 구조에 영향을 주지 않으면서 모든 대시보드 페이지가 아닌 대시보드 → 개요 페이지에만 적용됩니다.
여러 루트 레이아웃 생성하기
여러 루트 레이아웃을 만들려면 최상위 layout.js 파일을 제거하고 각 라우트 그룹 내부에 layout.js 파일을 추가하세요. 이는 완전히 다른 UI나 경험을 가진 섹션으로 애플리케이션을 분할하는 데 유용합니다. 각 루트 레이아웃에는 <html>과 <body> 태그를 추가해야 합니다.
전자상거래 사이트에서 고객용 쇼핑몰 페이지와 관리자용 대시보드 페이지가 완전히 다른 디자인을 가져야 할 때, 라우트 그룹을 사용하여 각각 다른 루트 레이아웃을 적용할 수 있습니다.
위의 예시에서 (marketing)과 (shop) 둘 다 각각의 루트 레이아웃을 가지고 있습니다.
'(준)공식 문서 > Next.js' 카테고리의 다른 글
| [ Next.js 15 공식 문서 ] Linking and Navigation (링킹과 네비게이션) (1) | 2025.07.17 |
|---|---|
| [ Next.js 15 공식 문서 ] Layouts and Pages (레이아웃과 페이지) (2) | 2025.07.16 |
| [ Next.js 공식 문서 ] Caching (0) | 2024.04.17 |
| [ Next.js 공식 문서 ] Rendering (2) - Composition Pattern (1) | 2024.04.15 |
| [ Next.js 공식 문서 ] Rendering (2) - Client Component (0) | 2024.04.14 |