Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
menu
  1. Home
  2. /Web Development
  3. /Nextjs
  4. /Project Structure
Your Progress0%
0 of 70 completed

NextJS Topics

Getting Started

  • What is Next.js?
  • Next.js vs React - Key Differences
  • Creating Your First Next.js 15 Project
  • Next.js Project Structure Explained
  • App Router vs Pages Router

Routing Fundamentals

  • File-Based Routing Basics
  • Creating Pages with page.tsx
  • Dynamic Routes and Route Parameters
  • Catch-All and Optional Catch-All Routes
  • Route Groups for Organization
  • Parallel Routes
  • Intercepting Routes

Layouts and Pages

  • Understanding Layouts
  • Root Layout and Global Configuration
  • Nested Layouts
  • Templates vs Layouts
  • Loading States with loading.tsx
  • Error Handling with error.tsx

Server and Client Components

  • Understanding Server Components
  • Client Components with 'use client'
  • When to Use Server vs Client Components
  • Component Composition Patterns
  • Passing Props Between Server and Client
  • Server Component Patterns and Best Practices

Data Fetching

  • Fetching Data in Server Components
  • Parallel and Sequential Data Fetching
  • Data Fetching Patterns and Strategies
  • Caching and Revalidation
  • Revalidate and Cache Tags
  • Handling Loading and Error States in Data Fetching

Navigation and Links

  • Link Component Basics
  • useRouter Hook for Programmatic Navigation
  • usePathname and useSearchParams Hooks
  • Active Links and Navigation States
  • Redirects and Navigation Guards

Styling in Next.js

  • CSS Modules in Next.js
  • Tailwind CSS Setup and Configuration
  • Global Styles and CSS Variables
  • Next.js Font Optimization

Images and Media

  • Next.js Image Component Basics
  • Image Optimization and Best Practices
  • Working with Static Assets

Forms and Data Mutations

  • Understanding Server Actions
  • Form Handling with Server Actions
  • Form Validation and Error Handling
  • useFormStatus and useFormState Hooks
  • Revalidating Data After Mutations
  • Optimistic Updates

Metadata and SEO

  • Static Metadata Configuration
  • Dynamic Metadata Generation
  • Open Graph and Social Media Cards
  • Sitemap and Robots.txt

API Routes and Route Handlers

  • Route Handlers Introduction
  • GET and POST Request Handlers
  • Dynamic API Routes
  • Request and Response Objects
  • API Error Handling and Status Codes

Middleware and Advanced Features

  • Introduction to Middleware
  • Authentication with Middleware
  • Environment Variables and Configuration
  • Streaming and Suspense
  • Not Found and Global Error Pages

Deployment and Optimization

  • Understanding Static and Dynamic Rendering
  • generateStaticParams for Static Generation
  • Build and Production Optimization
  • Deploying to Vercel
  • Alternative Deployment Options
  • Performance Monitoring and Analytics

Real-World Projects

  • Project 1: E-commerce Product Catalog
  • Project 2: Dashboard with Authentication

Next.js Project Structure Explained

Understanding every file and folder in your Next.js application

Now that you've created your first Next.js project, let's take a comprehensive tour of its structure. Understanding where everything goes and why will help you build applications confidently and follow Next.js conventions. By the end of this lesson, you'll know exactly what every file does and where to put your own code.

Project Structure Overview

A Next.js 15 project has a very organized structure. Let's look at the complete file tree first, then dive into each part:

Complete Next.js Project Structure

Click on any file or folder to learn its purpose

my-next-app

Select a file or folder to see details

The structure might seem overwhelming at first, but there are really only two directories you'll work in regularly:

  1. app/ - Where all your pages, routes, and layouts live
  2. public/ - Where you store static assets like images

Everything else is configuration or auto-generated. Let's understand each part!

The app Directory - Heart of Your Application

The app directory is where the magic happens. This is where you'll spend most of your time as a Next.js developer.

Why It's Called "App Router"

The App Router gets its name from this app directory. Everything inside app follows the App Router conventions and uses React Server Components by default. This is different from the older "Pages Router" which used a pages directory.

Key Principle: Folders = Routes

In Next.js, your folder structure is your routing structure. Each folder can potentially become a route in your URL.

How Folders Become Routes

See the direct connection between folders and URLs

📁 File Structure

app/
  page.tsx

🌐 URL Path

/

The root page.tsx creates your homepage at the / route.

🗂️ Folder Organization

Not every folder becomes a route! Only folders with a page.tsx file are publicly accessible. Folders withoutpage.tsx are just for organization.

Special Files in the app Directory

Next.js uses special file names with specific purposes. These files have "superpowers" that regular files don't have:

page.tsx - Creates a Route

Purpose: Makes a route segment publicly accessible

Required? Yes, if you want the route to be accessible

app/about/page.tsx
// This creates the /about route
export default function AboutPage() {
  return (
    <div>
      <h1>About Us</h1>
      <p>This is the about page.</p>
    </div>
  );
}

Without page.tsx, the folder is just for organization and won't create a public route.

layout.tsx - Shared UI

Purpose: Creates UI that wraps child pages and layouts

Required? Yes for root, optional for other routes

app/layout.tsx (Root Layout)
import type { Metadata } from 'next';
import './globals.css';

export const metadata: Metadata = {
  title: 'My Next.js App',
  description: 'Built with Next.js 15',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {/* This wraps ALL pages */}
        <nav>Navigation here</nav>
        {children}
        <footer>Footer here</footer>
      </body>
    </html>
  );
}

Key points:

  • Root layout must include <html> and <body> tags
  • Layouts don't re-render when navigating between pages
  • You can nest layouts for different sections
  • State persists in layouts during navigation

loading.tsx - Loading UI

Purpose: Automatic loading state with Suspense

Required? No, but very useful

app/dashboard/loading.tsx
export default function Loading() {
  return (
    <div className="flex items-center justify-center min-h-screen">
      <div className="animate-spin rounded-full h-32 w-32 border-b-2 border-gray-900" />
      <p className="ml-4">Loading dashboard...</p>
    </div>
  );
}

This automatically shows while the page is loading! Next.js wraps your page with React Suspense boundaries automatically.

error.tsx - Error Boundaries

Purpose: Catch and handle errors gracefully

Required? No, but recommended for production

app/dashboard/error.tsx
'use client'; // Error components must be Client Components

import { useEffect } from 'react';

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  useEffect(() => {
    // Log error to error reporting service
    console.error(error);
  }, [error]);

  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={() => reset()}>
        Try again
      </button>
    </div>
  );
}

Note: Error components must be Client Components (use "use client").

not-found.tsx - 404 Pages

Purpose: Custom 404 not found page

Required? No, Next.js has a default

app/not-found.tsx
import Link from 'next/link';

export default function NotFound() {
  return (
    <div className="flex flex-col items-center justify-center min-h-screen">
      <h1 className="text-6xl font-bold mb-4">404</h1>
      <h2 className="text-2xl mb-4">Page Not Found</h2>
      <p className="text-gray-600 mb-8">
        The page you're looking for doesn't exist.
      </p>
      <Link 
        href="/"
        className="px-6 py-3 bg-blue-600 text-white rounded-lg"
      >
        Go Home
      </Link>
    </div>
  );
}

route.ts - API Routes

Purpose: Create API endpoints (backend)

Required? Only if you need API endpoints

app/api/users/route.ts
// GET /api/users
export async function GET() {
  const users = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Jane' },
  ];
  
  return Response.json(users);
}

// POST /api/users
export async function POST(request: Request) {
  const body = await request.json();
  
  // Save to database...
  
  return Response.json(
    { message: 'User created', user: body },
    { status: 201 }
  );
}

Important: If a folder has route.ts, it cannot have page.tsx. It's one or the other!

template.tsx - Similar to Layout but Re-renders

Purpose: Like layout but creates new instance on navigation

Required? No, rarely used

Use template.tsx when you need state to reset on navigation, otherwise use layout.tsx.

Special File Naming Rules

  • These special files must be named exactly as shown (lowercase)
  • They must have the .tsx or .ts extension
  • They must export default a component (except metadata)
  • Typos won't work: Page.tsx or pages.tsx won't create routes

Organizing Code in the app Directory

Beyond special files, how should you organize your components, utils, and other code? Here are the common patterns:

1. Colocation - Keep Related Code Together

You can put any files in the app directory. Only special files like page.tsx are public.

PLAINTEXT
app/
  dashboard/
    page.tsx              ← Public route /dashboard
    DashboardHeader.tsx   ← Component used by page
    DashboardCard.tsx     ← Another component
    utils.ts              ← Helper functions
    types.ts              ← TypeScript types

2. Private Folders - Using Underscore

Folders starting with _ are private and won't become routes:

PLAINTEXT
app/
  _components/          ← Private folder (won't create route)
    Button.tsx
    Card.tsx
  _lib/                 ← Private folder
    utils.ts
    api.ts
  page.tsx              ← Public route /

3. Route Groups - Organizing Without URL Segments

Folders in parentheses (name) organize routes without affecting the URL:

PLAINTEXT
app/
  (marketing)/          ← Route group (not in URL)
    about/
      page.tsx          ← /about (not /marketing/about)
    contact/
      page.tsx          ← /contact
  (shop)/               ← Another route group
    products/
      page.tsx          ← /products
    cart/
      page.tsx          ← /cart

Use route groups to:

  • Organize routes into logical groups
  • Apply different layouts to different sections
  • Keep your file structure clean without affecting URLs

4. Recommended: Separate Components Folder

Many developers create a separate components folder at the root for shared components:

PLAINTEXT
my-next-app/
  app/                  ← Routes and pages
    page.tsx
    about/
      page.tsx
  components/           ← Shared components
    ui/
      Button.tsx
      Card.tsx
    layout/
      Header.tsx
      Footer.tsx
  lib/                  ← Shared utilities
    utils.ts
    db.ts

💡 Organization is Flexible

There's no single "right" way to organize your Next.js project. Choose a structure that makes sense for your team and project size. Start simple and refactor as your app grows!

The public Directory

The public folder is where you store static assets that don't need processing:

PLAINTEXT
public/
  images/
    logo.png
    hero.jpg
  fonts/
    custom-font.woff2
  robots.txt
  sitemap.xml
  favicon.ico

Accessing Public Files

Files in public are served from the root URL path:

TYPESCRIPT
// In your components
import Image from 'next/image';

export default function Header() {
  return (
    <div>
      {/* Reference files from public at root path */}
      <Image src="/images/logo.png" alt="Logo" width={200} height={50} />
      
      {/* robots.txt is at /robots.txt */}
      {/* Not /public/robots.txt */}
    </div>
  );
}

Important Public Directory Rules

  • Files are served at root path: /public/logo.png becomes /logo.png
  • Don't name files the same as routes (e.g., don't create public/about if you have app/about)
  • Only files in public at build time are served
  • For images you're importing in code, you can also put them in app

Configuration Files

Let's understand the important configuration files in your project root:

next.config.ts - Next.js Configuration

This file customizes Next.js behavior:

next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  // Allow images from external domains
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
      },
    ],
  },
  
  // Redirects
  async redirects() {
    return [
      {
        source: '/old-blog/:slug',
        destination: '/blog/:slug',
        permanent: true,
      },
    ];
  },
  
  // Environment variables available in browser
  env: {
    CUSTOM_KEY: 'my-value',
  },
};

export default nextConfig;

package.json - Project Metadata

Defines dependencies and scripts. The key scripts you'll use:

package.json
{
  "scripts": {
    "dev": "next dev --turbopack",      // Development server
    "build": "next build",                // Production build
    "start": "next start",                // Start production server
    "lint": "next lint"                   // Check code quality
  },
  "dependencies": {
    "next": "^15.0.0",                   // Next.js version
    "react": "^19.0.0",                  // React version
    "react-dom": "^19.0.0"
  }
}

tsconfig.json - TypeScript Configuration

Next.js has set this up perfectly. The key settings you might care about:

tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./*"]    // Allows @/app/... imports
    }
  }
}

This lets you write clean imports like import Button from '@/components/Button' instead of relative paths like ../../../components/Button.

.env.local - Environment Variables

Store secrets and configuration here:

.env.local
# Database
DATABASE_URL="postgresql://..."

# API Keys (server-side only)
API_SECRET_KEY="secret123"

# Public variables (exposed to browser)
NEXT_PUBLIC_API_URL="https://api.example.com"

Environment Variable Security

  • Server-only: Variables without NEXT_PUBLIC_ prefix
  • Browser-exposed: Variables with NEXT_PUBLIC_ prefix
  • Never commit .env.local to Git!
  • It's already in .gitignore by default

Auto-Generated Folders

These folders are automatically created and should never be edited manually:

.next Directory

Contains the build output. Created when you run npm run dev or npm run build.

  • Never edit files here
  • Safe to delete - regenerates automatically
  • Already in .gitignore

node_modules Directory

Contains all installed npm packages.

  • Created by npm install
  • Can be deleted and reinstalled anytime
  • Already in .gitignore
  • Can be very large (hundreds of MB)

Complete Project Example

Let's see a realistic project structure for a blog application:

Blog Application Structure

A practical example showing pages, layouts, and API routes

appImportant

Select a file or folder to see details

This structure creates these routes:

  • / - Homepage (app/page.tsx)
  • /about - About page (app/about/page.tsx)
  • /blog - Blog listing (app/blog/page.tsx)
  • /blog/my-post - Individual post (app/blog/[slug]/page.tsx)
  • /api/users - API endpoint (app/api/users/route.ts)

Best Practices for Project Structure

1. Start Simple, Refactor Later

Don't over-organize early. Begin with a flat structure and add folders as you need them. Premature organization can slow you down.

2. Colocate Related Code

Keep components, utilities, and types close to where they're used. This makes code easier to find and maintain.

3. Use Consistent Naming

  • Components: PascalCase (Button.tsx, UserCard.tsx)
  • Utilities: camelCase (formatDate.ts, api.ts)
  • Special files: Lowercase (page.tsx, layout.tsx)

4. Group by Feature, Not by Type

Good: Organize by feature/domain

PLAINTEXT
app/
  dashboard/
    page.tsx
    DashboardChart.tsx
    useDashboardData.ts
  profile/
    page.tsx
    ProfileForm.tsx
    updateProfile.ts

Less ideal: Organize by file type

PLAINTEXT
app/
  components/
    DashboardChart.tsx
    ProfileForm.tsx
  hooks/
    useDashboardData.ts
  utils/
    updateProfile.ts

This makes it harder to find related code when working on a feature.

5. Create a lib Folder for Shared Code

PLAINTEXT
my-next-app/
  lib/              ← Shared utilities
    db.ts           ← Database client
    auth.ts         ← Authentication helpers
    utils.ts        ← General utilities
    constants.ts    ← App-wide constants

Common Structure Mistakes to Avoid

❌ Don't create unnecessary nesting

PLAINTEXT
// Too deep for no reason
app/
  pages/           ← Unnecessary folder
    home/
      index/
        page.tsx   ← Just use app/page.tsx

❌ Don't mix special files incorrectly

PLAINTEXT
app/
  api/
    users/
      page.tsx    ← ERROR! Can't have both
      route.ts    ← page.tsx and route.ts

❌ Don't ignore naming conventions

PLAINTEXT
app/
  about/
    Page.tsx      ← Won't work! Must be lowercase
    pages.tsx     ← Won't work! Must be singular

❌ Don't put everything in the root

PLAINTEXT
my-next-app/
  component1.tsx   ← Keep components organized
  component2.tsx   ← in proper folders
  utils.ts
  helper.ts

What NOT to Commit to Git

Your .gitignore file is already set up, but here's what it excludes and why:

.gitignore
# Dependencies
node_modules/          # Large, can be reinstalled

# Build output
.next/                 # Generated files
out/                   # Export output

# Environment variables
.env.local             # Contains secrets!
.env*.local

# IDE files
.vscode/               # Editor settings (optional)
.idea/

# OS files
.DS_Store              # Mac system files
Thumbs.db              # Windows thumbnails

# Logs
npm-debug.log*
yarn-debug.log*

🔒 Security First

Never commit .env.local or any file containing API keys, passwords, or secrets. These belong only on your local machine and your deployment platform.

Key Takeaways

  • The app directory is where all routes and pages live
  • Folder structure in app creates URL routes
  • Special files like page.tsx, layout.tsxhave specific purposes
  • Only folders with page.tsx are publicly accessible
  • The public folder contains static assets served at root path
  • Configuration files like next.config.ts customize Next.js behavior
  • Never edit .next or node_modules manually
  • Use .env.local for secrets (never commit to Git)
  • Organize by feature/domain rather than by file type
  • Start simple and add structure as your app grows

What's Next?

Now that you understand the project structure and where everything goes, you're ready to learn about one of Next.js's most important features: the difference between the App Router and Pages Router.

In the next lesson, we'll compare these two routing systems, explain why the App Router is the future of Next.js, and make sure you understand why this tutorial series focuses exclusively on the App Router approach.

📁 Practice Exercise

Try creating this structure in your Next.js project:

  1. Create an app/about/page.tsx file
  2. Add a simple component that says "About Us"
  3. Navigate to http://localhost:3000/about
  4. See your new page appear automatically!

Test Your Understanding

Question 1 of 4

What is the purpose of the app directory in Next.js 15?

Understanding Next.js project structure? This comprehensive guide breaks down every file and folder!

Previous
Creating Your First Next.js 15 Project
Next
App Router vs Pages Router

Master Next.js Organization

Join 2,000+ developers learning Next.js best practices. Get the next lesson on the App Router delivered to your inbox - completely FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

NextJS Tutorials

0 of 70 completed

Your Progress0%

Topics

Getting Started

  • What is Next.js?
  • Next.js vs React - Key Differences
  • Creating Your First Next.js 15 Project
  • Next.js Project Structure Explained
  • App Router vs Pages Router

Routing Fundamentals

  • File-Based Routing Basics
  • Creating Pages with page.tsx
  • Dynamic Routes and Route Parameters
  • Catch-All and Optional Catch-All Routes
  • Route Groups for Organization
  • Parallel Routes
  • Intercepting Routes

Layouts and Pages

  • Understanding Layouts
  • Root Layout and Global Configuration
  • Nested Layouts
  • Templates vs Layouts
  • Loading States with loading.tsx
  • Error Handling with error.tsx

Server and Client Components

  • Understanding Server Components
  • Client Components with 'use client'
  • When to Use Server vs Client Components
  • Component Composition Patterns
  • Passing Props Between Server and Client
  • Server Component Patterns and Best Practices

Data Fetching

  • Fetching Data in Server Components
  • Parallel and Sequential Data Fetching
  • Data Fetching Patterns and Strategies
  • Caching and Revalidation
  • Revalidate and Cache Tags
  • Handling Loading and Error States in Data Fetching

Navigation and Links

  • Link Component Basics
  • useRouter Hook for Programmatic Navigation
  • usePathname and useSearchParams Hooks
  • Active Links and Navigation States
  • Redirects and Navigation Guards

Styling in Next.js

  • CSS Modules in Next.js
  • Tailwind CSS Setup and Configuration
  • Global Styles and CSS Variables
  • Next.js Font Optimization

Images and Media

  • Next.js Image Component Basics
  • Image Optimization and Best Practices
  • Working with Static Assets

Forms and Data Mutations

  • Understanding Server Actions
  • Form Handling with Server Actions
  • Form Validation and Error Handling
  • useFormStatus and useFormState Hooks
  • Revalidating Data After Mutations
  • Optimistic Updates

Metadata and SEO

  • Static Metadata Configuration
  • Dynamic Metadata Generation
  • Open Graph and Social Media Cards
  • Sitemap and Robots.txt

API Routes and Route Handlers

  • Route Handlers Introduction
  • GET and POST Request Handlers
  • Dynamic API Routes
  • Request and Response Objects
  • API Error Handling and Status Codes

Middleware and Advanced Features

  • Introduction to Middleware
  • Authentication with Middleware
  • Environment Variables and Configuration
  • Streaming and Suspense
  • Not Found and Global Error Pages

Deployment and Optimization

  • Understanding Static and Dynamic Rendering
  • generateStaticParams for Static Generation
  • Build and Production Optimization
  • Deploying to Vercel
  • Alternative Deployment Options
  • Performance Monitoring and Analytics

Real-World Projects

  • Project 1: E-commerce Product Catalog
  • Project 2: Dashboard with Authentication
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo