Next.js Project Structure
The folder tree
After create-next-app finishes (with the answers from the previous lesson) your project looks like this:
📁 my-first-app/ 📁 app/ # all routes (pages) live here layout.js # root layout: <html> and <body>, shared on every page page.js # the home page → / globals.css # CSS applied to the whole site favicon.ico # browser tab icon 📁 about/ page.js # → /about 📁 public/ # static files served as-is logo.png # → /logo.png 📁 node_modules/ # installed packages (never edit) 📁 .next/ # build output (auto-generated) next.config.mjs # Next.js settings package.json # project name, scripts, dependencies jsconfig.json # the @/* import alias AGENTS.md # notes for AI coding assistants
You will work almost entirely inside app/, plus folders you create such as components/ and lib/.
The app/ folder = your website's map
In the App Router, folders decide URLs. A folder becomes a URL segment, and the page.js inside it is what visitors see.
// app/about/page.js → http://localhost:3000/about
export default function AboutPage() {
return <h1>About us</h1>
}layout.js at the top of app/ is the root layout. It must contain <html> and <body>, and {children} is replaced by the current page:
// app/layout.js — wraps EVERY page
import './globals.css'
export const metadata = {
title: 'My First App',
description: 'Learning Next.js on CodingEasily',
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}Special file names
Next.js gives special meaning to certain file names inside app/. You will learn each one in later lessons:
| File | What it does |
|---|---|
page.js | The UI of a route — makes the URL public |
layout.js | Shared wrapper (header, footer) for a folder and its children |
loading.js | Shown instantly while the page loads |
error.js | Shown when something crashes in that part of the site |
not-found.js | The 404 page |
route.js | An API endpoint (Route Handler) instead of a page |
sitemap.js, robots.js | Generate /sitemap.xml and /robots.txt |
opengraph-image.js | Social-share image for the route |
Button.jsx) inside app/ is not a route. It is just a module you can import.public/ for images and files
Files in public/ are served exactly as they are, from the site root. Do not write public in the URL:
// public/logo.png is available at /logo.png <img src="/logo.png" alt="EduSite logo" width="120" height="40" />
Config files
- package.json — project name,
dev / build / startscripts and dependency versions. - package-lock.json — exact installed versions, so every computer installs the same thing.
- next.config.mjs — Next.js options: redirects, image settings, headers.
- jsconfig.json — the
@/*import alias. - .gitignore — keeps
node_modules,.nextand secret.env*.localfiles out of Git. - AGENTS.md — tells AI coding assistants to read the docs that match your Next.js version.
The @ import alias
// jsconfig.json
{
"compilerOptions": {
"paths": { "@/*": ["./*"] }
}
}
// Without alias (fragile):
import Header from '../../../components/Header'
// With alias (clean, works from any folder):
import Header from '@/components/Header'@/ always means "the project root", so imports never break when you move a file deeper.
Where to put your own code
A clean, common layout — the same one used by the EduSite project you will build:
📁 edusite/ 📁 app/ layout.jsx page.jsx globals.css not-found.jsx sitemap.js robots.js 📁 courses/ page.jsx [slug]/page.jsx 📁 blog/ page.jsx [slug]/page.jsx loading.jsx 📁 contact/ page.jsx ContactForm.jsx actions.js api/courses/route.js 📁 components/ Header.jsx Footer.jsx CourseCard.jsx 📁 lib/ courses.js posts.js site.js 📁 content/posts/ *.md 📁 public/images/ *.png proxy.js
- components/ — reusable UI pieces (Header, Card).
- lib/ — data and helper functions (database, Markdown reader).
- content/ — Markdown blog posts.
Common mistakes
- Creating
app/about.js— this does nothing. It must beapp/about/page.js. - Writing
src="/public/logo.png"— remove/public. - Deleting
<html>or<body>from the root layout — the app will not render. - Editing files inside
node_modulesor.next— changes are lost.
Summary
app/holds routes; folder = URL,page.js= the page.layout.jswraps pages; special names add loading, error, 404 and API behaviour.public/serves static files from/.- Use
@/imports and keep shared code incomponents/andlib/.
Create app/contact/page.js and app/courses/page.js with a heading each. Open /contact and /courses in the browser.
