This page provides an overview of all the folder and file conventions in Next.js, and recommendations for organizing your project.
Top-level folders are used to organize your application's code and static assets.
app | App Router |
pages | Pages Router |
public | Static assets to be served |
src | Optional application source folder |
Top-level files are used to configure your application, manage dependencies, run proxy, integrate monitoring tools, and define environment variables.
| Next.js | |
next.config.js | Configuration file for Next.js |
package.json | Project dependencies and scripts |
instrumentation.ts | OpenTelemetry and Instrumentation file |
proxy.ts | Next.js request proxy |
.env | Environment variables (should not be tracked by version control) |
.env.local | Local environment variables (should not be tracked by version control) |
.env.production | Production environment variables (should not be tracked by version control) |
.env.development | Development environment variables (should not be tracked by version control) |
eslint.config.mjs | Configuration file for ESLint |
.gitignore | Git files and folders to ignore |
next-env.d.ts | TypeScript declaration file for Next.js (should not be tracked by version control) |
tsconfig.json | Configuration file for TypeScript |
jsconfig.json | Configuration file for JavaScript |
Add page to expose a route, layout for shared UI such as header, nav, or footer, loading for skeletons, error for error boundaries, and route for APIs.
layout | .js .jsx .tsx | Layout |
page | .js .jsx .tsx | Page |
loading | .js .jsx .tsx | Loading UI |
not-found | .js .jsx .tsx | Not found UI |
error | .js .jsx .tsx | Error UI |
global-error | .js .jsx .tsx | Global error UI |
route | .js .ts | API endpoint |
template | .js .jsx .tsx | Re-rendered layout |
default | .js .jsx .tsx | Parallel route fallback page |
Folders define URL segments. Nesting folders nests segments. Layouts at any level wrap their child segments. A route becomes public when a page or route file exists.
| Path | URL pattern | Notes |
|---|---|---|
app/layout.tsx | — | Root layout wraps all routes |
app/blog/layout.tsx | — | Wraps /blog and descendants |
app/page.tsx | / | Public route |
app/blog/page.tsx | /blog | Public route |
app/blog/authors/page.tsx | /blog/authors | Public route |
Parameterize segments with square brackets. Use [segment] for a single param, [...segment] for catch‑all, and [[...segment]] for optional catch‑all. Access values via the params prop.
| Path | URL pattern |
|---|---|
app/blog/[slug]/page.tsx | /blog/my-first-post |
app/shop/[...slug]/page.tsx | /shop/clothing, /shop/clothing/shirts |
app/docs/[[...slug]]/page.tsx | /docs, /docs/layouts-and-pages, /docs/api-reference/use-router |
Organize code without changing URLs with route groups (group), and colocate non-routable files with private folders _folder.
| Path | URL pattern | Notes |
|---|---|---|
app/(marketing)/page.tsx | / | Group omitted from URL |
app/(shop)/cart/page.tsx | /cart | Share layouts within (shop) |
app/blog/_components/Post.tsx | — | Not routable; safe place for UI utilities |
app/blog/_lib/data.ts | — | Not routable; safe place for utils |
These features fit specific UI patterns, such as slot-based layouts or modal routing.
Use @slot for named slots rendered by a parent layout. Use intercept patterns to render another route inside the current layout without changing the URL, for example, to show a details view as a modal over a list.
| Pattern (docs) | Meaning | Typical use case |
|---|---|---|
@folder | Named slot | Sidebar + main content |
(.)folder | Intercept same level | Preview sibling route in a modal |
(..)folder | Intercept parent | Open a child of the parent as an overlay |
(..)(..)folder | Intercept two levels | Deeply nested overlay |
(...)folder | Intercept from root | Show arbitrary route in current view |
favicon | .ico | Favicon file |
icon | .ico .jpg .jpeg .png .svg | App Icon file |
icon | .js .ts .tsx | Generated App Icon |
apple-icon | .jpg .jpeg, .png | Apple App Icon file |
apple-icon | .js .ts .tsx | Generated Apple App Icon |
opengraph-image | .jpg .jpeg .png .gif | Open Graph image file |
opengraph-image | .js .ts .tsx | Generated Open Graph image |
twitter-image | .jpg .jpeg .png .gif | Twitter image file |
twitter-image | .js .ts .tsx | Generated Twitter image |
sitemap | .xml | Sitemap file |
sitemap | .js .ts | Generated Sitemap |
robots | .txt | Robots file |
robots | .js .ts | Generated Robots file |
Next.js is unopinionated about how you organize and colocate your project files. But it does provide several features to help you organize your project.
The components defined in special files are rendered in a specific hierarchy:
layout.jstemplate.jserror.js (React error boundary)loading.js (React suspense boundary)not-found.js (React error boundary for "not found" UI)page.js or nested layout.js
The components are rendered recursively in nested routes, meaning the components of a route segment will be nested inside the components of its parent segment.
In the app directory, nested folders define route structure. Each folder represents a route segment that is mapped to a corresponding segment in a URL path.
However, even though route structure is defined through folders, a route is not publicly accessible until a page.js or route.js file is added to a route segment.
And, even when a route is made publicly accessible, only the content returned by page.js or route.js is sent to the client.
This means that project files can be safely colocated inside route segments in the app directory without accidentally being routable.
Good to know: While you can colocate your project files in
appyou don't have to. If you prefer, you can keep them outside theappdirectory.
Private folders can be created by prefixing a folder with an underscore: _folderName
This indicates the folder is a private implementation detail and should not be considered by the routing system, thereby opting the folder and all its subfolders out of routing.
Since files in the app directory can be safely colocated by default, private folders are not required for colocation. However, they can be useful for:
Good to know:
- While not a framework convention, you might also consider marking files outside private folders as "private" using the same underscore pattern.
- You can create URL segments that start with an underscore by prefixing the folder name with
%5F(the URL-encoded form of an underscore):%5FfolderName.- If you don't use private folders, it would be helpful to know Next.js special file conventions to prevent unexpected naming conflicts.
Route groups can be created by wrapping a folder in parenthesis: (folderName)
This indicates the folder is for organizational purposes and should not be included in the route's URL path.
Route groups are useful for:
src folderNext.js supports storing application code (including app) inside an optional src folder. This separates application code from project configuration files which mostly live in the root of a project.
The following section lists a very high-level overview of common strategies. The simplest takeaway is to choose a strategy that works for you and your team and be consistent across the project.
Good to know: In our examples below, we're using
componentsandlibfolders as generalized placeholders, their naming has no special framework significance and your projects might use other folders likeui,utils,hooks,styles, etc.
appThis strategy stores all application code in shared folders in the root of your project and keeps the app directory purely for routing purposes.
appThis strategy stores all application code in shared folders in the root of the app directory.
This strategy stores globally shared application code in the root app directory and splits more specific application code into the route segments that use them.
To organize routes without affecting the URL, create a group to keep related routes together. The folders in parenthesis will be omitted from the URL (e.g. (marketing) or (shop)).
Even though routes inside (marketing) and (shop) share the same URL hierarchy, you can create a different layout for each group by adding a layout.js file inside their folders.
To opt specific routes into a layout, create a new route group (e.g. (shop)) and move the routes that share the same layout into the group (e.g. account and cart). The routes outside of the group will not share the layout (e.g. checkout).
To apply a loading skeleton via a loading.js file to a specific route, create a new route group (e.g., /(overview)) and then move your loading.tsx inside that route group.
Now, the loading.tsx file will only apply to your dashboard → overview page instead of all your dashboard pages without affecting the URL path structure.
To create multiple root layouts, remove the top-level layout.js file, and add a layout.js file inside each route group. This is useful for partitioning an application into sections that have a completely different UI or experience. The <html> and <body> tags need to be added to each root layout.
In the example above, both (marketing) and (shop) have their own root layout.
Folder and file conventions
네 개의 폴더 중 하나를 클릭해보세요. Next.js가 각 폴더에 어떤 특별한 역할을 부여하는지, 그리고 어떤 파일들이 거기에 속하는지 바로 확인할 수 있습니다. 폴더 이름을 임의로 바꾸면 프레임워크가 인식하지 못하기 때문에, 이 네 가지 이름은 암기할 가치가 있습니다.
App Router 기반 라우팅의 루트. layout, page, loading 등 특수 파일을 포함합니다.
Folder and file conventions
카테고리 버튼으로 파일을 걸러낸 뒤 각 파일을 클릭해보세요. 🔒 표시가 붙은 파일은 Git에 커밋하면 안 되는 파일입니다. .env 파일을 실수로 커밋하는 것은 흔한 보안 사고의 시작이기 때문에, 어느 파일이 버전 관리에서 제외되어야 하는지 아는 것이 중요합니다.
파일을 클릭하면 설명이 표시됩니다
Folder and file conventions
파일 아이콘을 하나씩 클릭해서 각 특수 파일의 역할과 코드 예시를 확인해보세요. page.tsx가 있어야만 URL이 활성화되고, loading.tsx 하나만 만들면 React Suspense 경계가 자동으로 생깁니다. App Router가 “파일 이름 = 기능 선언”이라는 패턴으로 동작한다는 것을 체감할 수 있습니다.
자식 세그먼트 전체를 감싸는 공유 UI. 페이지 이동 시 리렌더링되지 않습니다.
export default function Layout({ children }) {
return <div className="shell">{children}</div>
}Folder and file conventions
폴더 세그먼트를 추가하고 page 체크박스를 껐다 켜보세요. 마지막 폴더에 page.tsx가 없으면 URL이 빨간색으로 바뀌며 비공개 상태가 됩니다. 폴더를 만드는 것만으로는 URL이 생기지 않는다는 사실이 app/ 안에 컴포넌트 파일을 자유롭게 배치할 수 있는 이유입니다.
Folder and file conventions
패턴을 선택한 뒤 URL 입력란을 직접 수정해보세요. 예를 들어 [slug]에 /blog/a/b를 입력하면 매칭에 실패하지만 [...slug]는 성공합니다. 오른쪽의 params 객체가 실시간으로 바뀌는 것을 보면 각 패턴이 URL을 어떻게 파싱하는지 직관적으로 이해할 수 있습니다.
{
"slug": "my-first-post"
}Folder and file conventions
두 프리셋을 번갈아 클릭하며 파일 구조와 URL 결과를 비교해보세요. (marketing) 폴더는 URL에서 사라지고, _components 폴더는 🚫 표시와 함께 라우팅에서 완전히 제외됩니다. 괄호와 언더스코어라는 단순한 네이밍 규칙이 URL 설계와 코드 구조를 독립적으로 관리하게 해줍니다.
(marketing) 그룹은 URL에서 생략됩니다
Folder and file conventions
먼저 “@slot 병렬 라우트” 탭에서 슬롯을 클릭해 독립적으로 콘텐츠를 활성화해보세요. 그다음 “인터셉트 라우트” 탭으로 전환해 “사진 클릭” 버튼을 눌러 모달이 열리는 것을 확인하세요. 같은 URL 공간에서 두 가지 완전히 다른 UI 패턴이 가능하다는 것이 이 두 기능의 핵심입니다.
@slot 폴더는 Named Slot을 만듭니다. 부모 layout이 여러 슬롯을 동시에 받아 렌더링합니다.
슬롯을 클릭해서 활성화/비활성화해보세요
Folder and file conventions
카테고리를 필터링해서 파일 목록을 줄인 뒤, “코드 생성” 뱃지가 붙은 파일을 클릭해보세요. 정적 이미지 파일 하나만 올바른 위치에 두면 Next.js가 자동으로 head 태그를 만들어주고, .tsx 버전으로는 서버에서 동적으로 OG 이미지를 생성할 수도 있습니다. 파일 이름이 곧 기능 선언인 패턴을 메타데이터에서도 확인할 수 있습니다.
파일을 클릭하면 설명이 표시됩니다
Organizing your project
시뮬레이션 버튼 “에러 발생”을 클릭해보세요. error.js 레이어가 강조되면서 에러가 어느 경계에서 잡히는지 시각화됩니다. 그런 다음 각 레이어 박스를 직접 호버해 중첩 순서를 확인하면, error.tsx를 어느 폴더에 두느냐가 에러 처리 범위를 결정한다는 것을 이해할 수 있습니다.
Organizing your project
오른쪽 체크박스에서 dashboard 폴더의 page.tsx를 켜고 꺼보세요. 파일 트리에서 공개/비공개 상태가 즉시 바뀝니다. components 폴더는 체크박스가 없어도 파일 트리에 존재하는데, 이것이 바로 코로케이션의 핵심입니다 — page.tsx가 없는 폴더는 URL로 노출되지 않으므로 관련 컴포넌트를 라우트 가까이 마음껏 배치할 수 있습니다.
Organizing your project
components 폴더의 "_ 추가" 버튼을 클릭한 뒤, URL 시뮬레이터에 /components를 입력해보세요. 그런 다음 /_components도 입력해보면 둘 다 라우팅에서 차단된다는 것을 확인할 수 있습니다. 단순히 _를 붙이는 것만으로 "이 폴더는 라우트가 아님"을 팀 전체에 명시적으로 선언하는 효과가 있습니다.
%5F로 인코딩하세요 (예: %5FfolderName)Organizing your project
/checkout 라우트의 드롭다운을 (marketing)으로 바꿔보세요. 파일 트리에서는 marketing 그룹 안으로 이동하지만, 오른쪽의 URL 화살표(→ /checkout)는 그대로입니다. "그룹 표시" 체크박스를 해제하면 그룹이 사라지고 URL만 남는 것도 확인할 수 있습니다. 이것이 라우트 그룹의 핵심 — URL 설계와 코드 구조를 독립적으로 관리하는 것입니다.
(group)은 URL 경로에 포함되지 않습니다. 같은 그룹의 라우트들은 동일한 layout.tsx를 공유할 수 있습니다.Organizing your project
두 버튼을 번갈아 클릭해서 파일 트리를 비교해보세요. src/를 사용하면 next.config.js 같은 설정 파일들은 루트에 그대로 남고, 앱 코드만 src/ 안으로 들어갑니다. 설정 파일은 루트에 있어야 도구들이 자동으로 감지하기 때문에 src/ 안으로 옮길 수 없다는 점이 핵심입니다.
Examples
파일 트리에서 components/Button.tsx와 app/blog/page.tsx를 각각 클릭해보세요. 하나는 "앱 코드" 존, 다른 하나는 "라우팅" 존으로 구분됩니다. app/ 밖 전략의 핵심은 app/ 폴더를 순수한 라우팅 파일만 담는 공간으로 유지해서 폴더 구조만 봐도 라우팅 구조를 파악할 수 있게 하는 것입니다.
파일을 클릭하세요
Examples
파일 트리에서 _components/와 blog/ 폴더를 각각 클릭해보세요. 🔒 표시가 있는 폴더는 라우팅에서 제외됩니다. app/ 안에 모든 것을 넣으면서도 _ 접두사로 라우트와 공유 코드를 구분하는 이 전략은, "모든 코드가 한 곳에" 있으면서 "구조는 명확하게" 유지하는 실용적인 절충안입니다.
파일을 클릭하세요
Examples
blog/ 폴더를 펼쳐보세요 — page.tsx, layout.tsx 외에 components/PostCard.tsx, hooks/usePosts.ts까지 같은 폴더 안에 있습니다. 그다음 _shared/를 펼치면 여러 라우트에서 공유하는 파일만 모여 있습니다. blog를 삭제할 때 관련 파일을 전부 한 폴더만 지우면 된다는 것이 이 전략의 가장 큰 장점입니다.
Examples
/about 라우트를 (shop) 그룹으로 옮겨보세요. 파일 트리에서는 shop 아래로 이동하고 레이아웃 박스에서도 shop에 표시되지만, URL은 여전히 /about입니다. 이 데모는 라우트 그룹이 URL이 아닌 레이아웃 공유 범위를 정의한다는 것을 실제로 조작해보며 확인하는 연습입니다.
Examples
/checkout 체크박스를 해제해보세요. 파일 트리에서 checkout이 그룹 밖으로 빠져나오고 아래 레이아웃 박스에서도 "레이아웃 없음" 칸으로 이동합니다. 결제 페이지만 단순한 레이아웃을 쓰고 나머지 쇼핑 페이지는 공통 헤더를 공유하는, 실제 쇼핑몰에서 흔히 쓰이는 구조를 직접 만들어볼 수 있습니다.
Examples
"특정 라우트만" 버튼을 클릭한 뒤 /dashboard/settings의 "시뮬레이션" 버튼을 눌러보세요 — 비활성화되어 스켈레톤이 없습니다. "전체 적용"으로 돌아오면 settings도 활성화됩니다. loading.tsx를 어느 폴더에 두느냐가 Suspense 범위를 결정하기 때문에, 라우트 그룹이 "어느 페이지까지만 스켈레톤을 적용할 것인가"를 파일 구조로 표현하는 수단이 됩니다.
loading.tsx가 dashboard/ 최상위에 있으면 모든 하위 라우트에 적용됩니다.
Examples
"마케팅 섹션"과 "쇼핑 섹션" 버튼을 번갈아 클릭해보세요. HTML 테마 코드와 레이아웃 기능 목록이 완전히 달라집니다. 파일 트리 맨 위의 "app/ ← 여기에 layout.tsx 없음!" 경고가 핵심입니다 — 루트 레이아웃을 제거하고 각 그룹에 독립적인 html, body를 부여하는 이 패턴은 마케팅 사이트와 앱이 전혀 다른 디자인 시스템을 써야 할 때 쓰는 고급 구성입니다.
<html>과 <body> 태그가 필요합니다.This page provides an overview of all the folder and file conventions in Next.js, and recommendations for organizing your project.
Top-level folders are used to organize your application's code and static assets.
app | App Router |
pages | Pages Router |
public | Static assets to be served |
src | Optional application source folder |
Top-level files are used to configure your application, manage dependencies, run proxy, integrate monitoring tools, and define environment variables.
| Next.js | |
next.config.js | Configuration file for Next.js |
package.json | Project dependencies and scripts |
instrumentation.ts | OpenTelemetry and Instrumentation file |
proxy.ts | Next.js request proxy |
.env | Environment variables (should not be tracked by version control) |
.env.local | Local environment variables (should not be tracked by version control) |
.env.production | Production environment variables (should not be tracked by version control) |
.env.development | Development environment variables (should not be tracked by version control) |
eslint.config.mjs | Configuration file for ESLint |
.gitignore | Git files and folders to ignore |
next-env.d.ts | TypeScript declaration file for Next.js (should not be tracked by version control) |
tsconfig.json | Configuration file for TypeScript |
jsconfig.json | Configuration file for JavaScript |
Add page to expose a route, layout for shared UI such as header, nav, or footer, loading for skeletons, error for error boundaries, and route for APIs.
layout | .js .jsx .tsx | Layout |
page | .js .jsx .tsx | Page |
loading | .js .jsx .tsx | Loading UI |
not-found | .js .jsx .tsx | Not found UI |
error | .js .jsx .tsx | Error UI |
global-error | .js .jsx .tsx | Global error UI |
route | .js .ts | API endpoint |
template | .js .jsx .tsx | Re-rendered layout |
default | .js .jsx .tsx | Parallel route fallback page |
Folders define URL segments. Nesting folders nests segments. Layouts at any level wrap their child segments. A route becomes public when a page or route file exists.
| Path | URL pattern | Notes |
|---|---|---|
app/layout.tsx | — | Root layout wraps all routes |
app/blog/layout.tsx | — | Wraps /blog and descendants |
app/page.tsx | / | Public route |
app/blog/page.tsx | /blog | Public route |
app/blog/authors/page.tsx | /blog/authors | Public route |
Parameterize segments with square brackets. Use [segment] for a single param, [...segment] for catch‑all, and [[...segment]] for optional catch‑all. Access values via the params prop.
| Path | URL pattern |
|---|---|
app/blog/[slug]/page.tsx | /blog/my-first-post |
app/shop/[...slug]/page.tsx | /shop/clothing, /shop/clothing/shirts |
app/docs/[[...slug]]/page.tsx | /docs, /docs/layouts-and-pages, /docs/api-reference/use-router |
Organize code without changing URLs with route groups (group), and colocate non-routable files with private folders _folder.
| Path | URL pattern | Notes |
|---|---|---|
app/(marketing)/page.tsx | / | Group omitted from URL |
app/(shop)/cart/page.tsx | /cart | Share layouts within (shop) |
app/blog/_components/Post.tsx | — | Not routable; safe place for UI utilities |
app/blog/_lib/data.ts | — | Not routable; safe place for utils |
These features fit specific UI patterns, such as slot-based layouts or modal routing.
Use @slot for named slots rendered by a parent layout. Use intercept patterns to render another route inside the current layout without changing the URL, for example, to show a details view as a modal over a list.
| Pattern (docs) | Meaning | Typical use case |
|---|---|---|
@folder | Named slot | Sidebar + main content |
(.)folder | Intercept same level | Preview sibling route in a modal |
(..)folder | Intercept parent | Open a child of the parent as an overlay |
(..)(..)folder | Intercept two levels | Deeply nested overlay |
(...)folder | Intercept from root | Show arbitrary route in current view |
favicon | .ico | Favicon file |
icon | .ico .jpg .jpeg .png .svg | App Icon file |
icon | .js .ts .tsx | Generated App Icon |
apple-icon | .jpg .jpeg, .png | Apple App Icon file |
apple-icon | .js .ts .tsx | Generated Apple App Icon |
opengraph-image | .jpg .jpeg .png .gif | Open Graph image file |
opengraph-image | .js .ts .tsx | Generated Open Graph image |
twitter-image | .jpg .jpeg .png .gif | Twitter image file |
twitter-image | .js .ts .tsx | Generated Twitter image |
sitemap | .xml | Sitemap file |
sitemap | .js .ts | Generated Sitemap |
robots | .txt | Robots file |
robots | .js .ts | Generated Robots file |
Next.js is unopinionated about how you organize and colocate your project files. But it does provide several features to help you organize your project.
The components defined in special files are rendered in a specific hierarchy:
layout.jstemplate.jserror.js (React error boundary)loading.js (React suspense boundary)not-found.js (React error boundary for "not found" UI)page.js or nested layout.js
The components are rendered recursively in nested routes, meaning the components of a route segment will be nested inside the components of its parent segment.
In the app directory, nested folders define route structure. Each folder represents a route segment that is mapped to a corresponding segment in a URL path.
However, even though route structure is defined through folders, a route is not publicly accessible until a page.js or route.js file is added to a route segment.
And, even when a route is made publicly accessible, only the content returned by page.js or route.js is sent to the client.
This means that project files can be safely colocated inside route segments in the app directory without accidentally being routable.
Good to know: While you can colocate your project files in
appyou don't have to. If you prefer, you can keep them outside theappdirectory.
Private folders can be created by prefixing a folder with an underscore: _folderName
This indicates the folder is a private implementation detail and should not be considered by the routing system, thereby opting the folder and all its subfolders out of routing.
Since files in the app directory can be safely colocated by default, private folders are not required for colocation. However, they can be useful for:
Good to know:
- While not a framework convention, you might also consider marking files outside private folders as "private" using the same underscore pattern.
- You can create URL segments that start with an underscore by prefixing the folder name with
%5F(the URL-encoded form of an underscore):%5FfolderName.- If you don't use private folders, it would be helpful to know Next.js special file conventions to prevent unexpected naming conflicts.
Route groups can be created by wrapping a folder in parenthesis: (folderName)
This indicates the folder is for organizational purposes and should not be included in the route's URL path.
Route groups are useful for:
src folderNext.js supports storing application code (including app) inside an optional src folder. This separates application code from project configuration files which mostly live in the root of a project.
The following section lists a very high-level overview of common strategies. The simplest takeaway is to choose a strategy that works for you and your team and be consistent across the project.
Good to know: In our examples below, we're using
componentsandlibfolders as generalized placeholders, their naming has no special framework significance and your projects might use other folders likeui,utils,hooks,styles, etc.
appThis strategy stores all application code in shared folders in the root of your project and keeps the app directory purely for routing purposes.
appThis strategy stores all application code in shared folders in the root of the app directory.
This strategy stores globally shared application code in the root app directory and splits more specific application code into the route segments that use them.
To organize routes without affecting the URL, create a group to keep related routes together. The folders in parenthesis will be omitted from the URL (e.g. (marketing) or (shop)).
Even though routes inside (marketing) and (shop) share the same URL hierarchy, you can create a different layout for each group by adding a layout.js file inside their folders.
To opt specific routes into a layout, create a new route group (e.g. (shop)) and move the routes that share the same layout into the group (e.g. account and cart). The routes outside of the group will not share the layout (e.g. checkout).
To apply a loading skeleton via a loading.js file to a specific route, create a new route group (e.g., /(overview)) and then move your loading.tsx inside that route group.
Now, the loading.tsx file will only apply to your dashboard → overview page instead of all your dashboard pages without affecting the URL path structure.
To create multiple root layouts, remove the top-level layout.js file, and add a layout.js file inside each route group. This is useful for partitioning an application into sections that have a completely different UI or experience. The <html> and <body> tags need to be added to each root layout.
In the example above, both (marketing) and (shop) have their own root layout.
Folder and file conventions
네 개의 폴더 중 하나를 클릭해보세요. Next.js가 각 폴더에 어떤 특별한 역할을 부여하는지, 그리고 어떤 파일들이 거기에 속하는지 바로 확인할 수 있습니다. 폴더 이름을 임의로 바꾸면 프레임워크가 인식하지 못하기 때문에, 이 네 가지 이름은 암기할 가치가 있습니다.
App Router 기반 라우팅의 루트. layout, page, loading 등 특수 파일을 포함합니다.
Folder and file conventions
카테고리 버튼으로 파일을 걸러낸 뒤 각 파일을 클릭해보세요. 🔒 표시가 붙은 파일은 Git에 커밋하면 안 되는 파일입니다. .env 파일을 실수로 커밋하는 것은 흔한 보안 사고의 시작이기 때문에, 어느 파일이 버전 관리에서 제외되어야 하는지 아는 것이 중요합니다.
파일을 클릭하면 설명이 표시됩니다
Folder and file conventions
파일 아이콘을 하나씩 클릭해서 각 특수 파일의 역할과 코드 예시를 확인해보세요. page.tsx가 있어야만 URL이 활성화되고, loading.tsx 하나만 만들면 React Suspense 경계가 자동으로 생깁니다. App Router가 “파일 이름 = 기능 선언”이라는 패턴으로 동작한다는 것을 체감할 수 있습니다.
자식 세그먼트 전체를 감싸는 공유 UI. 페이지 이동 시 리렌더링되지 않습니다.
export default function Layout({ children }) {
return <div className="shell">{children}</div>
}Folder and file conventions
폴더 세그먼트를 추가하고 page 체크박스를 껐다 켜보세요. 마지막 폴더에 page.tsx가 없으면 URL이 빨간색으로 바뀌며 비공개 상태가 됩니다. 폴더를 만드는 것만으로는 URL이 생기지 않는다는 사실이 app/ 안에 컴포넌트 파일을 자유롭게 배치할 수 있는 이유입니다.
Folder and file conventions
패턴을 선택한 뒤 URL 입력란을 직접 수정해보세요. 예를 들어 [slug]에 /blog/a/b를 입력하면 매칭에 실패하지만 [...slug]는 성공합니다. 오른쪽의 params 객체가 실시간으로 바뀌는 것을 보면 각 패턴이 URL을 어떻게 파싱하는지 직관적으로 이해할 수 있습니다.
{
"slug": "my-first-post"
}Folder and file conventions
두 프리셋을 번갈아 클릭하며 파일 구조와 URL 결과를 비교해보세요. (marketing) 폴더는 URL에서 사라지고, _components 폴더는 🚫 표시와 함께 라우팅에서 완전히 제외됩니다. 괄호와 언더스코어라는 단순한 네이밍 규칙이 URL 설계와 코드 구조를 독립적으로 관리하게 해줍니다.
(marketing) 그룹은 URL에서 생략됩니다
Folder and file conventions
먼저 “@slot 병렬 라우트” 탭에서 슬롯을 클릭해 독립적으로 콘텐츠를 활성화해보세요. 그다음 “인터셉트 라우트” 탭으로 전환해 “사진 클릭” 버튼을 눌러 모달이 열리는 것을 확인하세요. 같은 URL 공간에서 두 가지 완전히 다른 UI 패턴이 가능하다는 것이 이 두 기능의 핵심입니다.
@slot 폴더는 Named Slot을 만듭니다. 부모 layout이 여러 슬롯을 동시에 받아 렌더링합니다.
슬롯을 클릭해서 활성화/비활성화해보세요
Folder and file conventions
카테고리를 필터링해서 파일 목록을 줄인 뒤, “코드 생성” 뱃지가 붙은 파일을 클릭해보세요. 정적 이미지 파일 하나만 올바른 위치에 두면 Next.js가 자동으로 head 태그를 만들어주고, .tsx 버전으로는 서버에서 동적으로 OG 이미지를 생성할 수도 있습니다. 파일 이름이 곧 기능 선언인 패턴을 메타데이터에서도 확인할 수 있습니다.
파일을 클릭하면 설명이 표시됩니다
Organizing your project
시뮬레이션 버튼 “에러 발생”을 클릭해보세요. error.js 레이어가 강조되면서 에러가 어느 경계에서 잡히는지 시각화됩니다. 그런 다음 각 레이어 박스를 직접 호버해 중첩 순서를 확인하면, error.tsx를 어느 폴더에 두느냐가 에러 처리 범위를 결정한다는 것을 이해할 수 있습니다.
Organizing your project
오른쪽 체크박스에서 dashboard 폴더의 page.tsx를 켜고 꺼보세요. 파일 트리에서 공개/비공개 상태가 즉시 바뀝니다. components 폴더는 체크박스가 없어도 파일 트리에 존재하는데, 이것이 바로 코로케이션의 핵심입니다 — page.tsx가 없는 폴더는 URL로 노출되지 않으므로 관련 컴포넌트를 라우트 가까이 마음껏 배치할 수 있습니다.
Organizing your project
components 폴더의 "_ 추가" 버튼을 클릭한 뒤, URL 시뮬레이터에 /components를 입력해보세요. 그런 다음 /_components도 입력해보면 둘 다 라우팅에서 차단된다는 것을 확인할 수 있습니다. 단순히 _를 붙이는 것만으로 "이 폴더는 라우트가 아님"을 팀 전체에 명시적으로 선언하는 효과가 있습니다.
%5F로 인코딩하세요 (예: %5FfolderName)Organizing your project
/checkout 라우트의 드롭다운을 (marketing)으로 바꿔보세요. 파일 트리에서는 marketing 그룹 안으로 이동하지만, 오른쪽의 URL 화살표(→ /checkout)는 그대로입니다. "그룹 표시" 체크박스를 해제하면 그룹이 사라지고 URL만 남는 것도 확인할 수 있습니다. 이것이 라우트 그룹의 핵심 — URL 설계와 코드 구조를 독립적으로 관리하는 것입니다.
(group)은 URL 경로에 포함되지 않습니다. 같은 그룹의 라우트들은 동일한 layout.tsx를 공유할 수 있습니다.Organizing your project
두 버튼을 번갈아 클릭해서 파일 트리를 비교해보세요. src/를 사용하면 next.config.js 같은 설정 파일들은 루트에 그대로 남고, 앱 코드만 src/ 안으로 들어갑니다. 설정 파일은 루트에 있어야 도구들이 자동으로 감지하기 때문에 src/ 안으로 옮길 수 없다는 점이 핵심입니다.
Examples
파일 트리에서 components/Button.tsx와 app/blog/page.tsx를 각각 클릭해보세요. 하나는 "앱 코드" 존, 다른 하나는 "라우팅" 존으로 구분됩니다. app/ 밖 전략의 핵심은 app/ 폴더를 순수한 라우팅 파일만 담는 공간으로 유지해서 폴더 구조만 봐도 라우팅 구조를 파악할 수 있게 하는 것입니다.
파일을 클릭하세요
Examples
파일 트리에서 _components/와 blog/ 폴더를 각각 클릭해보세요. 🔒 표시가 있는 폴더는 라우팅에서 제외됩니다. app/ 안에 모든 것을 넣으면서도 _ 접두사로 라우트와 공유 코드를 구분하는 이 전략은, "모든 코드가 한 곳에" 있으면서 "구조는 명확하게" 유지하는 실용적인 절충안입니다.
파일을 클릭하세요
Examples
blog/ 폴더를 펼쳐보세요 — page.tsx, layout.tsx 외에 components/PostCard.tsx, hooks/usePosts.ts까지 같은 폴더 안에 있습니다. 그다음 _shared/를 펼치면 여러 라우트에서 공유하는 파일만 모여 있습니다. blog를 삭제할 때 관련 파일을 전부 한 폴더만 지우면 된다는 것이 이 전략의 가장 큰 장점입니다.
Examples
/about 라우트를 (shop) 그룹으로 옮겨보세요. 파일 트리에서는 shop 아래로 이동하고 레이아웃 박스에서도 shop에 표시되지만, URL은 여전히 /about입니다. 이 데모는 라우트 그룹이 URL이 아닌 레이아웃 공유 범위를 정의한다는 것을 실제로 조작해보며 확인하는 연습입니다.
Examples
/checkout 체크박스를 해제해보세요. 파일 트리에서 checkout이 그룹 밖으로 빠져나오고 아래 레이아웃 박스에서도 "레이아웃 없음" 칸으로 이동합니다. 결제 페이지만 단순한 레이아웃을 쓰고 나머지 쇼핑 페이지는 공통 헤더를 공유하는, 실제 쇼핑몰에서 흔히 쓰이는 구조를 직접 만들어볼 수 있습니다.
Examples
"특정 라우트만" 버튼을 클릭한 뒤 /dashboard/settings의 "시뮬레이션" 버튼을 눌러보세요 — 비활성화되어 스켈레톤이 없습니다. "전체 적용"으로 돌아오면 settings도 활성화됩니다. loading.tsx를 어느 폴더에 두느냐가 Suspense 범위를 결정하기 때문에, 라우트 그룹이 "어느 페이지까지만 스켈레톤을 적용할 것인가"를 파일 구조로 표현하는 수단이 됩니다.
loading.tsx가 dashboard/ 최상위에 있으면 모든 하위 라우트에 적용됩니다.
Examples
"마케팅 섹션"과 "쇼핑 섹션" 버튼을 번갈아 클릭해보세요. HTML 테마 코드와 레이아웃 기능 목록이 완전히 달라집니다. 파일 트리 맨 위의 "app/ ← 여기에 layout.tsx 없음!" 경고가 핵심입니다 — 루트 레이아웃을 제거하고 각 그룹에 독립적인 html, body를 부여하는 이 패턴은 마케팅 사이트와 앱이 전혀 다른 디자인 시스템을 써야 할 때 쓰는 고급 구성입니다.
<html>과 <body> 태그가 필요합니다.