# Next.js Documentation
> Index of all docs: /docs/llms.txt
@doc-version: >=v16.3.1
@doc-version-notes: Some features may have extended or refined behavior in minor or patch releases
@router: App Router
@router-note: Unless otherwise noted in each section, these documents apply to the App Router
---
title: Getting Started
description: Learn how to create full-stack web applications with the Next.js App Router.
url: "https://nextjs.org/docs/app/getting-started"
version: 16.3.1
---
# Getting Started
Welcome to the Next.js documentation!
This **Getting Started** section will help you create your first Next.js app and learn the core features you'll use in every project.
## Pre-requisite knowledge
Our documentation assumes some familiarity with web development. Before getting started, it'll help if you're comfortable with:
* HTML
* CSS
* JavaScript
* React
If you're new to React or need a refresher, we recommend starting with our [React Foundations course](/learn/react-foundations), and the [Next.js Foundations course](/learn/dashboard-app) that has you building an application as you learn.
## Next Steps
- [Installation](/docs/app/getting-started/installation)
- [Project Structure](/docs/app/getting-started/project-structure)
- [Layouts and Pages](/docs/app/getting-started/layouts-and-pages)
- [Linking and Navigating](/docs/app/getting-started/linking-and-navigating)
- [Server and Client Components](/docs/app/getting-started/server-and-client-components)
- [Fetching Data](/docs/app/getting-started/fetching-data)
- [Mutating Data](/docs/app/getting-started/mutating-data)
- [Caching](/docs/app/getting-started/caching)
- [Revalidating](/docs/app/getting-started/revalidating)
- [Error Handling](/docs/app/getting-started/error-handling)
- [CSS](/docs/app/getting-started/css)
- [Image Optimization](/docs/app/getting-started/images)
- [Font Optimization](/docs/app/getting-started/fonts)
- [Metadata and OG images](/docs/app/getting-started/metadata-and-og-images)
- [Route Handlers](/docs/app/getting-started/route-handlers)
- [Proxy](/docs/app/getting-started/proxy)
- [Deploying](/docs/app/getting-started/deploying)
- [Upgrading](/docs/app/getting-started/upgrading)
---
title: Installation
description: "Learn how to create a new Next.js application with the `create-next-app` CLI, and set up TypeScript, ESLint, and Module Path Aliases."
url: "https://nextjs.org/docs/app/getting-started/installation"
version: 16.3.1
---
# Installation
Create a new Next.js app and run it locally.
## Quick start
1. Create a new Next.js app named `my-app`
2. `cd my-app` and start the dev server.
3. Visit `http://localhost:3000`.
```bash package="pnpm"
pnpm create next-app@latest my-app --yes
cd my-app
pnpm dev
```
```bash package="npm"
npx create-next-app@latest my-app --yes
cd my-app
npm run dev
```
```bash package="yarn"
yarn create next-app@latest my-app --yes
cd my-app
yarn dev
```
```bash package="bun"
bun create next-app@latest my-app --yes
cd my-app
bun dev
```
* `--yes` skips prompts using saved preferences or defaults. The default setup enables TypeScript, Tailwind CSS, ESLint, App Router, and Turbopack, with import alias `@/*`, and includes `AGENTS.md` (with a `CLAUDE.md` that references it) to guide coding agents to write up-to-date Next.js code.
## System requirements
Before you begin, make sure your development environment meets the following requirements:
* Minimum Node.js version: [20.9](https://nodejs.org/)
* Operating systems: macOS, Windows (including WSL), and Linux.
## Supported browsers
Next.js supports modern browsers with zero configuration.
* Chrome 111+
* Edge 111+
* Firefox 111+
* Safari 16.4+
Learn more about [browser support](/docs/architecture/supported-browsers), including how to configure polyfills and target specific browsers.
## Create with the CLI
The quickest way to create a new Next.js app is using [`create-next-app`](/docs/app/api-reference/cli/create-next-app), which sets up everything automatically for you. To create a project, run:
```bash package="pnpm"
pnpm create next-app
```
```bash package="npm"
npx create-next-app@latest
```
```bash package="yarn"
yarn create next-app
```
```bash package="bun"
bun create next-app
```
On installation, you'll see the following prompts:
```txt filename="Terminal"
What is your project named? my-app
Would you like to use the recommended Next.js defaults?
Yes, use recommended defaults - TypeScript, ESLint, Tailwind CSS, App Router, AGENTS.md
No, reuse previous settings
No, customize settings - Choose your own preferences
```
If you choose to `customize settings`, you'll see the following prompts:
```txt filename="Terminal"
Would you like to use TypeScript? No / Yes
Which linter would you like to use? ESLint / Biome / None
Would you like to use React Compiler? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like your code inside a `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to customize the import alias (`@/*` by default)? No / Yes
What import alias would you like configured? @/*
Would you like to include AGENTS.md to guide coding agents to write up-to-date Next.js code? No / Yes
```
After the prompts, [`create-next-app`](/docs/app/api-reference/cli/create-next-app) will create a folder with your project name and install the required dependencies.
## Manual installation
To manually create a new Next.js app, install the required packages:
```bash package="pnpm"
pnpm i next@latest react@latest react-dom@latest
```
```bash package="npm"
npm i next@latest react@latest react-dom@latest
```
```bash package="yarn"
yarn add next@latest react@latest react-dom@latest
```
```bash package="bun"
bun add next@latest react@latest react-dom@latest
```
> **Good to know**:
>
> * The `App Router` uses [React canary releases](https://react.dev/blog/2023/05/03/react-canaries) built-in, which include all the stable React 19 changes, as well as newer features being validated in frameworks, but you should still declare react and react-dom in package.json for tooling and ecosystem compatibility.
> * The `Pages Router` uses the React version from your `package.json`.
Then, add the following scripts to your `package.json` file:
```json filename="package.json"
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint",
"lint:fix": "eslint --fix"
}
}
```
These scripts refer to the different stages of developing an application:
* `next dev`: Starts the development server using Turbopack (default bundler).
* `next build`: Builds the application for production.
* `next start`: Starts the production server.
* `eslint`: Runs ESLint.
Turbopack is now the default bundler. To use Webpack run `next dev --webpack` or `next build --webpack`. See the [Turbopack docs](/docs/app/api-reference/turbopack) for configuration details.
### Create the `app` directory
Next.js uses file-system routing, which means the routes in your application are determined by how you structure your files.
Create an `app` folder. Then, inside `app`, create a `layout.tsx` file. This file is the [root layout](/docs/app/api-reference/file-conventions/layout#root-layout). It's required and must contain the `` and `
` tags.
```tsx filename="app/layout.tsx" switcher
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
{children}
)
}
```
```jsx filename="app/layout.js" switcher
export default function RootLayout({ children }) {
return (
{children}
)
}
```
Create a home page `app/page.tsx` with some initial content:
```tsx filename="app/page.tsx" switcher
export default function Page() {
return
}
```
Both `layout.tsx` and `page.tsx` will be rendered when the user visits the root of your application (`/`).

> **Good to know**:
>
> * If you forget to create the root layout, Next.js will automatically create this file when running the development server with `next dev`.
> * You can optionally use a [`src` folder](/docs/app/api-reference/file-conventions/src-folder) in the root of your project to separate your application's code from configuration files.
### Create the `public` folder (optional)
Create a [`public` folder](/docs/app/api-reference/file-conventions/public-folder) at the root of your project to store static assets such as images, fonts, etc. Files inside `public` can then be referenced by your code starting from the base URL (`/`).
You can then reference these assets using the root path (`/`). For example, `public/profile.png` can be referenced as `/profile.png`:
```tsx filename="app/page.tsx" highlight={4} switcher
import Image from 'next/image'
export default function Page() {
return
}
```
```jsx filename="app/page.js" highlight={4} switcher
import Image from 'next/image'
export default function Page() {
return
}
```
## Run the development server
1. Run `npm run dev` to start the development server.
2. Visit `http://localhost:3000` to view your application.
3. Edit the `app/page.tsx` file and save it to see the updated result in your browser.
## Set up TypeScript
> Minimum TypeScript version: `v5.1.0`
Next.js comes with built-in TypeScript support. To add TypeScript to your project, rename a file to `.ts` / `.tsx` and run `next dev`. Next.js will automatically install the necessary dependencies and add a `tsconfig.json` file with the recommended config options.
### IDE Plugin
Next.js includes a custom TypeScript plugin and type checker, which VSCode and other code editors can use for advanced type-checking and auto-completion.
You can enable the plugin in VS Code by:
1. Opening the command palette (`Ctrl/⌘` + `Shift` + `P`)
2. Searching for "TypeScript: Select TypeScript Version"
3. Selecting "Use Workspace Version"

See the [TypeScript reference](/docs/app/api-reference/config/typescript) page for more information.
## Set up your editor
The App Router names files by convention, like `page.tsx`, `layout.tsx`, and `route.ts`, so your editor quickly fills with same-named tabs. Label each tab with its enclosing folders, like `blog/[id]`, so you can tell them apart.
In VS Code 1.88+ or Cursor, add [custom editor labels](https://code.visualstudio.com/updates/v1_88#_customize-editor-labels) to `.vscode/settings.json`. Labeling two folders deep keeps dynamic routes like `blog/[id]/page.tsx` from all collapsing to the same `[id]` label:
```json filename=".vscode/settings.json"
{
"workbench.editor.customLabels.patterns": {
"**/app/**/page.tsx": "${dirname(1)}/${dirname} - page.tsx",
"**/app/**/layout.tsx": "${dirname(1)}/${dirname} - layout.tsx",
"**/app/**/loading.tsx": "${dirname(1)}/${dirname} - loading.tsx",
"**/app/**/error.tsx": "${dirname(1)}/${dirname} - error.tsx",
"**/app/**/not-found.tsx": "${dirname(1)}/${dirname} - not-found.tsx",
"**/app/**/template.tsx": "${dirname(1)}/${dirname} - template.tsx",
"**/app/**/default.tsx": "${dirname(1)}/${dirname} - default.tsx",
"**/app/**/route.ts": "${dirname(1)}/${dirname} - route.ts"
}
}
```
Or copy this prompt to have your coding agent set it up:
```prompt
Set up custom editor labels so my Next.js App Router files are easy to tell apart. Read https://nextjs.org/docs/app/getting-started/installation#set-up-your-editor and add the workbench.editor.customLabels.patterns config shown there to my .vscode/settings.json, creating the file if it doesn't exist. Adjust the labels to taste. If I use a different editor, apply the equivalent setting or tell me it's automatic, and leave my other settings untouched.
```
> **Good to know:** JetBrains IDEs (WebStorm, IntelliJ) show the folder for same-named files automatically, so no setup is needed.
## Set up linting
Next.js supports linting with either ESLint or Biome. Choose a linter and run it directly via `package.json` scripts.
* Use **ESLint** (comprehensive rules):
```json filename="package.json"
{
"scripts": {
"lint": "eslint",
"lint:fix": "eslint --fix"
}
}
```
* Or use **Biome** (fast linter + formatter):
```json filename="package.json"
{
"scripts": {
"lint": "biome check",
"format": "biome format --write"
}
}
```
If your project previously used `next lint`, migrate your scripts to the ESLint CLI with the codemod:
```bash filename="Terminal"
npx @next/codemod@canary next-lint-to-eslint-cli .
```
If you use ESLint, create an explicit config (recommended `eslint.config.mjs`). ESLint supports both [the legacy `.eslintrc.*` and the newer `eslint.config.mjs` formats](https://eslint.org/docs/latest/use/configure/configuration-files#configuring-eslint). See the [ESLint API reference](/docs/app/api-reference/config/eslint#with-core-web-vitals) for a recommended setup.
> **Good to know**: Starting with Next.js 16, `next build` no longer runs the linter automatically. Instead, you can run your linter through NPM scripts.
See the [ESLint Plugin](/docs/app/api-reference/config/eslint) page for more information.
## Set up Absolute Imports and Module Path Aliases
Next.js has in-built support for the `"paths"` and `"baseUrl"` options of `tsconfig.json` and `jsconfig.json` files.
These options allow you to alias project directories to absolute paths, making it easier and cleaner to import modules. For example:
```jsx
// Before
import { Button } from '../../../components/button'
// After
import { Button } from '@/components/button'
```
To configure absolute imports, add the `baseUrl` configuration option to your `tsconfig.json` or `jsconfig.json` file. For example:
```json filename="tsconfig.json or jsconfig.json"
{
"compilerOptions": {
"baseUrl": "src/"
}
}
```
In addition to configuring the `baseUrl` path, you can use the `"paths"` option to `"alias"` module paths.
For example, the following configuration maps `@/components/*` to `components/*`:
```json filename="tsconfig.json or jsconfig.json"
{
"compilerOptions": {
"baseUrl": "src/",
"paths": {
"@/styles/*": ["styles/*"],
"@/components/*": ["components/*"]
}
}
}
```
Each of the `"paths"` are relative to the `baseUrl` location.
## Upgrade your Next.js app
Keep your Next.js version up to date. Each release ships security patches, bug fixes, and performance optimizations alongside new features, and staying current keeps every individual upgrade small. Run the `upgrade` command:
```bash package="pnpm"
pnpm next upgrade
```
```bash package="npm"
npx next upgrade
```
```bash package="yarn"
yarn next upgrade
```
```bash package="bun"
bunx next upgrade
```
Upgrading also updates the documentation bundled inside the `next` package at `node_modules/next/dist/docs/`. New features arrive with their docs, and existing pages pick up new guidance and pitfalls discovered along the way. [AI coding agents](/docs/app/guides/ai-agents) in your project then work from the version you have installed rather than their training data. After an upgrade, you can prompt your agent to catch up:
```prompt
Let's get our Next.js knowledge up to speed, and give me a summary of what's new for you
```
See [Upgrading](/docs/app/getting-started/upgrading) for version guides and manual upgrade steps, or the [preview docs](https://preview.nextjs.org) to explore features before they ship in a stable version.
---
title: Project Structure
description: Learn the folder and file conventions in Next.js, and how to organize your project.
url: "https://nextjs.org/docs/app/getting-started/project-structure"
version: 16.3.1
---
# Project Structure
This page provides an overview of **all** the folder and file conventions in Next.js, and recommendations for organizing your project.
## Folder and file conventions
### Top-level folders
Top-level folders are used to organize your application's code and static assets.

| | |
| ------------------------------------------------------------------ | ---------------------------------- |
| [`app`](/docs/app) | App Router |
| [`pages`](/docs/pages/building-your-application/routing) | Pages Router |
| [`public`](/docs/app/api-reference/file-conventions/public-folder) | Static assets to be served |
| [`src`](/docs/app/api-reference/file-conventions/src-folder) | Optional application source folder |
### Top-level files
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`](/docs/app/api-reference/config/next-config-js) | Configuration file for Next.js |
| [`package.json`](/docs/app/getting-started/installation#manual-installation) | Project dependencies and scripts |
| [`instrumentation.ts`](/docs/app/guides/instrumentation) | OpenTelemetry and Instrumentation file |
| [`proxy.ts`](/docs/app/api-reference/file-conventions/proxy) | Next.js request proxy |
| [`.env`](/docs/app/guides/environment-variables) | Environment variables (should not be tracked by version control) |
| [`.env.local`](/docs/app/guides/environment-variables) | Local environment variables (should not be tracked by version control) |
| [`.env.production`](/docs/app/guides/environment-variables) | Production environment variables (should not be tracked by version control) |
| [`.env.development`](/docs/app/guides/environment-variables) | Development environment variables (should not be tracked by version control) |
| [`eslint.config.mjs`](/docs/app/api-reference/config/eslint) | Configuration file for ESLint |
| `.gitignore` | Git files and folders to ignore |
| [`next-env.d.ts`](/docs/app/api-reference/config/typescript#next-envdts) | 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 |
### Routing Files
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`](/docs/app/api-reference/file-conventions/layout) | `.js` `.jsx` `.tsx` | Layout |
| [`page`](/docs/app/api-reference/file-conventions/page) | `.js` `.jsx` `.tsx` | Page |
| [`loading`](/docs/app/api-reference/file-conventions/loading) | `.js` `.jsx` `.tsx` | Loading UI |
| [`not-found`](/docs/app/api-reference/file-conventions/not-found) | `.js` `.jsx` `.tsx` | Not found UI |
| [`error`](/docs/app/api-reference/file-conventions/error) | `.js` `.jsx` `.tsx` | Error UI |
| [`global-error`](/docs/app/api-reference/file-conventions/error#global-error) | `.js` `.jsx` `.tsx` | Global error UI |
| [`route`](/docs/app/api-reference/file-conventions/route) | `.js` `.ts` | API endpoint |
| [`template`](/docs/app/api-reference/file-conventions/template) | `.js` `.jsx` `.tsx` | Re-rendered layout |
| [`default`](/docs/app/api-reference/file-conventions/default) | `.js` `.jsx` `.tsx` | Parallel route fallback page |
### Nested routes
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 |
### Dynamic routes
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`](/docs/app/api-reference/file-conventions/page#params-optional) 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` |
### Route groups and private folders
Organize code without changing URLs with route groups [`(group)`](/docs/app/api-reference/file-conventions/route-groups#convention), and colocate non-routable files with private folders [`_folder`](#private-folders).
| 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 |
### Parallel and Intercepted Routes
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`](/docs/app/api-reference/file-conventions/parallel-routes#slots) | Named slot | Sidebar + main content |
| [`(.)folder`](/docs/app/api-reference/file-conventions/intercepting-routes#convention) | Intercept same level | Preview sibling route in a modal |
| [`(..)folder`](/docs/app/api-reference/file-conventions/intercepting-routes#convention) | Intercept parent | Open a child of the parent as an overlay |
| [`(..)(..)folder`](/docs/app/api-reference/file-conventions/intercepting-routes#convention) | Intercept two levels | Deeply nested overlay |
| [`(...)folder`](/docs/app/api-reference/file-conventions/intercepting-routes#convention) | Intercept from root | Show arbitrary route in current view |
### Metadata file conventions
#### App icons
| | | |
| --------------------------------------------------------------------------------------------------------------- | ----------------------------------- | ------------------------ |
| [`favicon`](/docs/app/api-reference/file-conventions/metadata/app-icons#favicon) | `.ico` | Favicon file |
| [`icon`](/docs/app/api-reference/file-conventions/metadata/app-icons#icon) | `.ico` `.jpg` `.jpeg` `.png` `.svg` | App Icon file |
| [`icon`](/docs/app/api-reference/file-conventions/metadata/app-icons#generate-icons-using-code-js-ts-tsx) | `.js` `.ts` `.tsx` | Generated App Icon |
| [`apple-icon`](/docs/app/api-reference/file-conventions/metadata/app-icons#apple-icon) | `.jpg` `.jpeg` `.png` | Apple App Icon file |
| [`apple-icon`](/docs/app/api-reference/file-conventions/metadata/app-icons#generate-icons-using-code-js-ts-tsx) | `.js` `.ts` `.tsx` | Generated Apple App Icon |
#### Open Graph and Twitter images
| | | |
| --------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------------------------- |
| [`opengraph-image`](/docs/app/api-reference/file-conventions/metadata/opengraph-image#opengraph-image) | `.jpg` `.jpeg` `.png` `.gif` | Open Graph image file |
| [`opengraph-image`](/docs/app/api-reference/file-conventions/metadata/opengraph-image#generate-images-using-code-js-ts-tsx) | `.js` `.ts` `.tsx` | Generated Open Graph image |
| [`twitter-image`](/docs/app/api-reference/file-conventions/metadata/opengraph-image#twitter-image) | `.jpg` `.jpeg` `.png` `.gif` | Twitter image file |
| [`twitter-image`](/docs/app/api-reference/file-conventions/metadata/opengraph-image#generate-images-using-code-js-ts-tsx) | `.js` `.ts` `.tsx` | Generated Twitter image |
#### SEO
| | | |
| ------------------------------------------------------------------------------------------------------------ | ----------- | --------------------- |
| [`sitemap`](/docs/app/api-reference/file-conventions/metadata/sitemap#sitemap-files-xml) | `.xml` | Sitemap file |
| [`sitemap`](/docs/app/api-reference/file-conventions/metadata/sitemap#generating-a-sitemap-using-code-js-ts) | `.js` `.ts` | Generated Sitemap |
| [`robots`](/docs/app/api-reference/file-conventions/metadata/robots#static-robotstxt) | `.txt` | Robots file |
| [`robots`](/docs/app/api-reference/file-conventions/metadata/robots#generate-a-robots-file) | `.js` `.ts` | Generated Robots file |
## Organizing your project
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.
### Component hierarchy
The components defined in special files are rendered in a specific hierarchy:
* `layout.js`
* `template.js`
* `error.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.

### Colocation
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 `app` you don't **have** to. If you prefer, you can [keep them outside the `app` directory](#store-project-files-outside-of-app).
### Private folders
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](#colocation), private folders are not required for colocation. However, they can be useful for:
* Separating UI logic from routing logic.
* Consistently organizing internal files across a project and the Next.js ecosystem.
* Sorting and grouping files in code editors.
* Avoiding potential naming conflicts with future Next.js file conventions.
> **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](/docs/app/getting-started/project-structure#routing-files) to prevent unexpected naming conflicts.
### Route groups
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:
* Organizing routes by site section, intent, or team. e.g. marketing pages, admin pages, etc.
* Enabling nested layouts in the same route segment level:
* [Creating multiple nested layouts in the same segment, including multiple root layouts](#creating-multiple-root-layouts)
* [Adding a layout to a subset of routes in a common segment](#opting-specific-segments-into-a-layout)
### `src` folder
Next.js supports storing application code (including `app`) inside an optional [`src` folder](/docs/app/api-reference/file-conventions/src-folder). This separates application code from project configuration files which mostly live in the root of a project.

## Examples
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 `components` and `lib` folders as generalized placeholders, their naming has no special framework significance and your projects might use other folders like `ui`, `utils`, `hooks`, `styles`, etc.
### Store project files outside of `app`
This strategy stores all application code in shared folders in the **root of your project** and keeps the `app` directory purely for routing purposes.

### Store project files in top-level folders inside of `app`
This strategy stores all application code in shared folders in the **root of the `app` directory**.

### Split project files by feature or route
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.

### Organize routes without affecting the URL path
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. These layouts nest within the existing app layout.

### Opting specific segments into a layout
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`).

### Opting for loading skeletons on a specific route
To apply a [loading skeleton](/docs/app/api-reference/file-conventions/loading) 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.
### Creating multiple root layouts
To create multiple [root layouts](/docs/app/api-reference/file-conventions/layout#root-layout), 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 `` and `` tags need to be added to each root layout.

In the example above, both `(marketing)` and `(shop)` have their own root layout.
---
title: Layouts and Pages
description: Learn how to create your first pages and layouts, and link between them with the Link component.
url: "https://nextjs.org/docs/app/getting-started/layouts-and-pages"
version: 16.3.1
---
# Layouts and Pages
Next.js uses **file-system based routing**, meaning you can use folders and files to define routes. This page will guide you through how to create layouts and pages, and link between them.
## Creating a page
A **page** is UI that is rendered on a specific route. To create a page, add a [`page` file](/docs/app/api-reference/file-conventions/page) inside the `app` directory and default export a React component. For example, to create an index page (`/`):

```tsx filename="app/page.tsx" switcher
export default function Page() {
return
}
```
## Creating a layout
A layout is UI that is **shared** between multiple pages. On navigation, layouts preserve state, remain interactive, and do not rerender.
You can define a layout by default exporting a React component from a [`layout` file](/docs/app/api-reference/file-conventions/layout). The component should accept a `children` prop which can be a page or another [layout](#nesting-layouts).
For example, to create a layout that accepts your index page as child, add a `layout` file inside the `app` directory:

```tsx filename="app/layout.tsx" switcher
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
{/* Layout UI */}
{/* Place children where you want to render a page or nested layout */}
{children}
)
}
```
```jsx filename="app/layout.js" switcher
export default function DashboardLayout({ children }) {
return (
{/* Layout UI */}
{/* Place children where you want to render a page or nested layout */}
{children}
)
}
```
The layout above is called a [root layout](/docs/app/api-reference/file-conventions/layout#root-layout) because it's defined at the root of the `app` directory. The root layout is **required** and must contain `html` and `body` tags.
## Creating a nested route
A nested route is a route composed of multiple URL segments. For example, the `/blog/[slug]` route is composed of three segments:
* `/` (Root Segment)
* `blog` (Segment)
* `[slug]` (Leaf Segment)
In Next.js:
* **Folders** are used to define the route segments that map to URL segments.
* **Files** (like `page` and `layout`) are used to create UI that is shown for a segment.
To create nested routes, you can nest folders inside each other. For example, to add a route for `/blog`, create a folder called `blog` in the `app` directory. Then, to make `/blog` publicly accessible, add a `page.tsx` file:

```tsx filename="app/blog/page.tsx" switcher
// Dummy imports
import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'
export default async function Page() {
const posts = await getPosts()
return (
{posts.map((post) => (
))}
)
}
```
```jsx filename="app/blog/page.js" switcher
// Dummy imports
import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'
export default async function Page() {
const posts = await getPosts()
return (
{posts.map((post) => (
))}
)
}
```
You can continue nesting folders to create nested routes. For example, to create a route for a specific blog post, create a new `[slug]` folder inside `blog` and add a `page` file:

```tsx filename="app/blog/[slug]/page.tsx" switcher
function generateStaticParams() {}
export default function Page() {
return
Hello, Blog Post Page!
}
```
```jsx filename="app/blog/[slug]/page.js" switcher
function generateStaticParams() {}
export default function Page() {
return
Hello, Blog Post Page!
}
```
Wrapping a folder name in square brackets (e.g. `[slug]`) creates a [dynamic route segment](/docs/app/api-reference/file-conventions/dynamic-routes) which is used to generate multiple pages from data. e.g. blog posts, product pages, etc.
## Nesting layouts
By default, layouts in the folder hierarchy are also nested, which means they wrap child layouts via their `children` prop. You can nest layouts by adding `layout` inside specific route segments (folders).
For example, to create a layout for the `/blog` route, add a new `layout` file inside the `blog` folder.

```tsx filename="app/blog/layout.tsx" switcher
export default function BlogLayout({
children,
}: {
children: React.ReactNode
}) {
return {children}
}
```
```jsx filename="app/blog/layout.js" switcher
export default function BlogLayout({ children }) {
return {children}
}
```
If you were to combine the two layouts above, the root layout (`app/layout.js`) would wrap the blog layout (`app/blog/layout.js`), which would wrap the blog (`app/blog/page.js`) and blog post page (`app/blog/[slug]/page.js`).
## Creating a dynamic segment
[Dynamic segments](/docs/app/api-reference/file-conventions/dynamic-routes) allow you to create routes that are generated from data. For example, instead of manually creating a route for each individual blog post, you can create a dynamic segment to generate the routes based on blog post data.
To create a dynamic segment, wrap the segment (folder) name in square brackets: `[segmentName]`. For example, in the `app/blog/[slug]/page.tsx` route, the `[slug]` is the dynamic segment.
```tsx filename="app/blog/[slug]/page.tsx" switcher
export default async function BlogPostPage({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params
const post = await getPost(slug)
return (
)
}
```
Learn more about [Dynamic Segments](/docs/app/api-reference/file-conventions/dynamic-routes) and the [`params`](/docs/app/api-reference/file-conventions/page#params-optional) props.
Nested [layouts within Dynamic Segments](/docs/app/api-reference/file-conventions/layout#params-optional), can also access the `params` props.
## Rendering with search params
In a Server Component **page**, you can access search parameters using the [`searchParams`](/docs/app/api-reference/file-conventions/page#searchparams-optional) prop:
```tsx filename="app/page.tsx" switcher
export default async function Page({
searchParams,
}: {
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
const filters = (await searchParams).filters
}
```
```jsx filename="app/page.jsx" switcher
export default async function Page({ searchParams }) {
const filters = (await searchParams).filters
}
```
Using `searchParams` opts your page into [**dynamic rendering**](/docs/app/glossary#dynamic-rendering) because it requires an incoming request to read the search parameters from.
Client Components can read search params using the [`useSearchParams`](/docs/app/api-reference/functions/use-search-params) hook.
Learn more about `useSearchParams` in [prerendered](/docs/app/api-reference/functions/use-search-params#prerendering) and [dynamically rendered](/docs/app/api-reference/functions/use-search-params#dynamic-rendering) routes.
### What to use and when
* Use the `searchParams` prop when you need search parameters to **load data for the page** (e.g. pagination, filtering from a database).
* Use `useSearchParams` when search parameters are used **only on the client** (e.g. filtering a list already loaded via props).
* As a small optimization, you can use `new URLSearchParams(window.location.search)` in **callbacks or event handlers** to read search params without triggering re-renders.
## Linking between pages
You can use the [`` component](/docs/app/api-reference/components/link) to navigate between routes. `` is a built-in Next.js component that extends the HTML `` tag to provide [prefetching](/docs/app/getting-started/linking-and-navigating#prefetching) and [client-side navigation](/docs/app/getting-started/linking-and-navigating#client-side-transitions).
For example, to generate a list of blog posts, import `` from `next/link` and pass a `href` prop to the component:
```tsx filename="app/ui/post.tsx" highlight={1,2,11} switcher
import Link from 'next/link'
import { getPosts } from '@/lib/posts'
export default async function Posts() {
const posts = await getPosts()
return (