Skip to content

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

  1. Separate routing from components/modules
  2. Use Next.js conventions: Route groups ((folder)) and private folders (_folder)
  3. Leverage colocation: Keep related files together
  4. Prioritize scalability and maintainability
bash
/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:

bash
app/
  (dashboard)/       # URL: /dashboard/...
    analytics/
      page.tsx
    settings/
      page.tsx
  (marketing)/       # URL: /marketing/...
    blog/
      page.tsx

Layout file in route group:

tsx
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:

bash
app/
  _components/   # Not accessible via URL
    Card.tsx
    Form.tsx
  _hooks/        # Local hooks
  _lib/          # Local utilities

3. Component Organization

bash
/src
  /components
    /ui              # Primitive UI (buttons, inputs)
    /dashboard       # Feature-specific components
    /auth            # Auth-related components
    /shared          # Common components

4. File Conventions

  • layout.tsx: Shared layout
  • page.tsx: Route entry point
  • loading.tsx: Route-specific loading
  • error.tsx: Route-specific error

Folder Structure Examples

Default Structure

bash
/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:

tsx
'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:

bash
/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

  1. Keep /app focused on routing:

    • Use route groups ((group)) for logical separation
    • Reserve for page files and route-specific assets
  2. Colocate local components:

    • Place route-specific components in _components folders
    • Keep shared UI in top-level /components
  3. Differentiate server/client components:

    • Default to server components (app/ folder)
    • Only use client components when necessary
  4. Separate concerns:

    • /lib for business logic and utilities
    • /components for visual elements
    • /services for API interactions
    • /types for type definitions
  5. Use strict naming conventions:

    • _folder for non-routes
    • (group) for route grouping
    • page.tsx for route entry points

Implementation Tips

Creating a Login Route

bash
app/
  (auth)/
    login/
      page.tsx    # Handles /login
tsx
export default function LoginPage() {
  return (
    <main>
      <LoginForm />
    </main>
  )
}

Sharing Layouts

tsx
export default function AuthLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <div className="auth-container">
      <div className="auth-card">
        {children}
      </div>
    </div>
  )
}

Organizing Components

bash
src/
  components/
    auth/          # Auth-specific components
      LoginForm.tsx
      SignupCard.tsx
    dashboard/     # Dashboard components
      StatsCard.tsx
    ui/            # Reusable primitives
      Button.tsx
      Input.tsx

Alternative Approaches

  1. Flat structure:

    bash
    app/
      _components/
      login/
        page.tsx

    Best for small projects

  2. Domain-Driven Design (for complex apps):

    bash
    src/
      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.