Next.js 13 App Router Folder Structure
Problem: Organizing Your Project
When starting with Next.js 13's App Router, developers often struggle with:
- Where to place routes like
/login
and/register
- How to organize UI components efficiently
- How to separate routing concerns from other application logic
- Maintaining a scalable structure that teams can understand
With the introduction of App Router (replacing pages/
), Next.js 13 introduces new conventions for folder organization.
Solution: Folder Structure Best Practices
Core Principles
- Separate routing from components/modules
- Use Next.js conventions: Route groups (
(folder)
) and private folders (_folder
) - Leverage colocation: Keep related files together
- Prioritize scalability and maintainability
Recommended Structure
/src (optional)
/app # App Router directory
(routes) # Route group - not in URL
/dashboard
/profile
(auth) # Authentication route group
/login
page.tsx # /login route
/register
page.tsx # /register route
_components # Private folder (not a route)
ui/
layout/
_lib # Utilities/helpers
utils.ts
layout.tsx # Root layout
page.tsx # Home page (/)
/components # Shared UI components
/common # Reusable elements
/lib # Global utilities
constants.ts
api/
/styles # Global styles
Key Implementation Details
1. Route Groups for Organization
Group related routes without affecting URLs:
app/
(dashboard)/ # URL: /dashboard/...
analytics/
page.tsx
settings/
page.tsx
(marketing)/ # URL: /marketing/...
blog/
page.tsx
Layout file in route group:
export default function AuthLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="min-h-screen bg-gray-100">
<AuthHeader />
{children}
<Footer />
</div>
)
}
2. Private Folders for Non-Route Content
Prefix folders with _
to exclude from routing:
app/
_components/ # Not accessible via URL
Card.tsx
Form.tsx
_hooks/ # Local hooks
_lib/ # Local utilities
3. Component Organization
/src
/components
/ui # Primitive UI (buttons, inputs)
/dashboard # Feature-specific components
/auth # Auth-related components
/shared # Common components
4. File Conventions
layout.tsx
: Shared layoutpage.tsx
: Route entry pointloading.tsx
: Route-specific loadingerror.tsx
: Route-specific error
Folder Structure Examples
Default Structure
/my-app
/app
(routes)
/dashboard
_components/
Chart.tsx
page.tsx
(auth)
/login
page.tsx
_components
Button.tsx
layout.tsx
/public
next.config.js
Server Component Default
Components in app/
are Server Components by default. Add 'use client'
directive at the top for client components:
'use client' // Client component
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
)
}
Advanced Organization Options
For larger projects, consider these additions:
/src
/app # Routing only
/components # Global UI components
/lib # Utilities and helpers
/api # API services
/constants # Application constants
/validation # Validation schemas
/providers # Context providers
/hooks # Custom hooks
/styles # Global styles
/types # TypeScript types
/store # State management (Zustand/Redux)
Best Practices Summary
Keep
/app
focused on routing:- Use route groups (
(group)
) for logical separation - Reserve for page files and route-specific assets
- Use route groups (
Colocate local components:
- Place route-specific components in
_components
folders - Keep shared UI in top-level
/components
- Place route-specific components in
Differentiate server/client components:
- Default to server components (
app/
folder) - Only use client components when necessary
- Default to server components (
Separate concerns:
/lib
for business logic and utilities/components
for visual elements/services
for API interactions/types
for type definitions
Use strict naming conventions:
_folder
for non-routes(group)
for route groupingpage.tsx
for route entry points
Implementation Tips
Creating a Login Route
app/
(auth)/
login/
page.tsx # Handles /login
export default function LoginPage() {
return (
<main>
<LoginForm />
</main>
)
}
Sharing Layouts
export default function AuthLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="auth-container">
<div className="auth-card">
{children}
</div>
</div>
)
}
Organizing Components
src/
components/
auth/ # Auth-specific components
LoginForm.tsx
SignupCard.tsx
dashboard/ # Dashboard components
StatsCard.tsx
ui/ # Reusable primitives
Button.tsx
Input.tsx
Alternative Approaches
Flat structure:
bashapp/ _components/ login/ page.tsx
Best for small projects
Domain-Driven Design (for complex apps):
bashsrc/ modules/ auth/ components/ pages/ services/ dashboard/ components/ pages/
Avoid
- Putting non-route files directly in
app/
without_
prefix - Mixing route segments and components without organization
- Duplicating component names across different areas
By following these patterns, you'll create a maintainable Next.js project that scales well as your application grows and your team expands. For larger projects, consider combining route groups, private folders, and a src
directory structure for maximum clarity.