Next.js File Structure

Organize a Next.js project with the app folder, route groups, private folders, and colocated files.

TL;DR

  1. Put routes in the app folder and static files in public.
  2. Group related routes with (folder) names without changing any URL.
  3. Hide helper folders from routing by prefixing them with _.

Top-Level Folders

    app/

    Holds every route, layout, and API endpoint in the App Router.

    app/
      layout.tsx
      page.tsx
      blog/
        page.tsx
    public/

    Serves static files like images and icons from the root of the site.

    public/
      logo.svg       # served at /logo.svg
      og.png         # served at /og.png
    src/

    Optionally move app inside src to separate your code from config files.

    src/
      app/
      components/
      lib/
    next.config.ts
    package.json

Root Files

    next.config.ts

    Configure Next.js options such as images, redirects, and Turbopack in this file.

    import type { NextConfig } from 'next';
    
    const nextConfig: NextConfig = {};
    
    export default nextConfig;
    proxy.ts

    Run code before a request completes; it replaces middleware.ts in Next.js 16.

    // proxy.ts (project root, or inside src)
    export function proxy(request: Request) {
      // redirects, rewrites, headers
    }
    .env.local

    Keep local secrets in this file and never commit it to git.

    # .env.local  (ignored by git)
    DATABASE_URL="postgres://..."
    
    # .env        (shared defaults)
    NEXT_PUBLIC_SITE_NAME="My App"

Special Files in app

    page.tsx and layout.tsx

    A page makes a route public, and a layout wraps that page and its children.

    app/dashboard/
      layout.tsx     # shared shell
      page.tsx       # /dashboard
    loading.tsx and error.tsx

    Show a fallback while a route segment loads or after it throws an error.

    app/dashboard/
      loading.tsx    # shown while loading
      error.tsx      # shown after an error
      not-found.tsx  # shown by notFound()
    route.ts

    Create an API endpoint at the folder path by exporting HTTP method functions.

    app/api/posts/
      route.ts       # /api/posts

Organizing Routes

    (group)

    Wrap a folder name in parentheses to group routes without adding a URL segment.

    app/
      (marketing)/
        about/page.tsx     # /about
      (shop)/
        cart/page.tsx      # /cart
    _folder

    Prefix a folder with an underscore to keep it out of routing entirely.

    app/blog/
      _components/
        PostCard.tsx       # never a route
      page.tsx
    Colocation

    Keep helper files beside the route that uses them; only page.tsx is public.

    app/dashboard/
      page.tsx
      Chart.tsx            # not routable
      Chart.test.tsx
    @/ alias

    Import from the project root with @/ instead of long relative paths.

    import { Button } from '@/components/Button';
    import { formatDate } from '@/lib/dates';

Tips

  1. Keep components next to the route that uses them, and move a component to a shared components folder once two routes need it.
  2. Use the @/ import alias from create-next-app so files keep working when you move them between folders.

Warnings

  1. A folder cannot contain both page.tsx and route.ts, because one path cannot be a page and an endpoint.
  2. Files in public are served to everyone, so never store secrets or private data in that folder.

In Practice

FAQ