If you're learning React in 2026, you've probably heard one piece of advice repeatedly:
"Use Next.js."
But when you first open a Next.js project, it can feel overwhelming:
- What's the
appfolder? - Why are some components running on the server?
- When should I use
"use client"? - Do I still need API routes?
This guide answers those questions and gives you a practical cheat sheet you can bookmark and revisit whenever you're building a Next.js application.
What is Next.js?
Next.js is a React framework that helps you build fast, production-ready web applications.
It comes with:
- File-based routing
- Server-side rendering
- Static site generation
- API routes
- Image optimization
- SEO support
- Server Components
- Full-stack capabilities
Think of it as React + everything you need to build and deploy a modern application.
TL;DR: Next.js Cheat Sheet
| Feature | What It Does | Example |
|---|---|---|
| Create App | Create a new Next.js project | npx create-next-app@latest my-app |
| Route | Create a page |
app/about/page.tsx → /about
|
| Dynamic Route | Create URL parameters | app/blog/[slug]/page.tsx |
| Layout | Shared UI between pages | app/layout.tsx |
| Server Component | Default component type | async function Page() |
| Client Component | Enables state & events | "use client" |
| Navigation | Link between pages | <Link href="/about" /> |
| Router | Navigate programmatically | router.push("/dashboard") |
| Search Params | Read URL query values | useSearchParams() |
| Metadata | SEO configuration | export const metadata = {} |
| Data Fetching | Fetch server-side data | await fetch(url) |
| Revalidation | Refresh cached data | revalidate: 3600 |
| No Cache | Always fetch fresh data | cache: "no-store" |
| Server Actions | Handle forms on the server | "use server" |
| Loading UI | Show loading states | app/loading.tsx |
| Error UI | Handle route errors | app/error.tsx |
| Not Found | Custom 404 page | app/not-found.tsx |
| API Route | Create backend endpoints | app/api/users/route.ts |
| Middleware | Run code before requests | middleware.ts |
| Images | Optimized image loading | <Image /> |
| Fonts | Built-in font optimization | next/font/google |
| Environment Variables | Store secrets/config | process.env |
| Static Rendering | Pre-render pages | Default caching behavior |
| Dynamic Rendering | Render on every request | cache: "no-store" |
| Production Build | Create deployable build | npm run build |
| Deploy | Deploy instantly | Vercel, Docker, AWS, etc. |
Golden Rule
| Need... | Use |
|---|---|
State (useState) |
Client Component |
| Event Handlers | Client Component |
| Browser APIs | Client Component |
| Database Access | Server Component |
| API Calls | Server Component |
| Better SEO | Server Component |
| Smaller Bundle Size | Server Component |
| Form Submission | Server Action |
| Shared Navigation | Layout |
| Dynamic URLs |
[slug] Routes |
Folder Structure Cheat Sheet
app/
├── layout.tsx # Shared layout
├── page.tsx # Home page
├── loading.tsx # Loading UI
├── error.tsx # Error UI
├── not-found.tsx # 404 page
├── api/
│ └── users/
│ └── route.ts
└── blog/
└── [slug]/
└── page.tsx
The 5 Things Every Beginner Should Memorise
- Every folder becomes a route.
- Components are Server Components by default.
- Add
"use client"only when needed. - Fetch data directly inside Server Components.
- Use Server Actions for forms instead of creating unnecessary API routes.
1. Create a New Next.js Project
Create a project:
npx create-next-app@latest my-app
With TypeScript:
npx create-next-app@latest my-app --typescript
Move into the project:
cd my-app
Start the development server:
npm run dev
Visit:
http://localhost:3000
2. Understanding the App Router
Modern Next.js applications use the App Router.
A typical project looks like this:
app/
├── layout.tsx
├── page.tsx
├── loading.tsx
├── error.tsx
├── not-found.tsx
└── dashboard/
└── page.tsx
Every folder becomes a route automatically.
For example:
app/page.tsx
→ /
app/about/page.tsx
→ /about
app/dashboard/page.tsx
→ /dashboard
No routing configuration needed.
3. Pages vs Layouts
A page represents a route.
export default function Page() {
return <h1>Hello World</h1>;
}
A layout wraps multiple pages.
export default function Layout({
children,
}: {
children: React.ReactNode;
}) {
return (
<main>
{children}
</main>
);
}
Layouts persist between page navigations, making them perfect for:
- Navigation bars
- Sidebars
- Footers
- Shared UI
4. Dynamic Routes
Need a blog post page?
Create:
app/blog/[slug]/page.tsx
Example URL:
/blog/nextjs-cheatsheet
Access the slug:
export default async function BlogPost({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
return <h1>{slug}</h1>;
}
5. Server Components (Default)
One of the biggest changes in modern Next.js is that components are Server Components by default.
Example:
export default async function Page() {
const users = await fetch(
"https://jsonplaceholder.typicode.com/users"
).then((res) => res.json());
return <div>{users.length} users found</div>;
}
Benefits:
- Smaller JavaScript bundles
- Better performance
- Better SEO
- Secure access to databases and APIs
6. Client Components
Need state, event handlers, or browser APIs?
Use:
"use client";
Example:
"use client";
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
Use Client Components when you need:
useStateuseEffect- Event handlers
- Browser APIs
- Custom hooks
Otherwise, stay with Server Components.
7. Navigation
Link between pages:
import Link from "next/link";
<Link href="/about">
About
</Link>
Programmatic navigation:
"use client";
import { useRouter } from "next/navigation";
const router = useRouter();
router.push("/dashboard");
router.replace("/login");
router.back();
8. Search Parameters
URL:
/products?page=2
Read the value:
"use client";
import { useSearchParams } from "next/navigation";
const params = useSearchParams();
const page = params.get("page");
Result:
"2"
9. Metadata and SEO
Static metadata:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "My Website",
description: "Built with Next.js",
};
Dynamic metadata:
export async function generateMetadata() {
return {
title: "Blog Post",
};
}
This automatically generates SEO-friendly meta tags.
10. Data Fetching
Simple fetch:
const data = await fetch(url);
Cache for one hour:
await fetch(url, {
next: {
revalidate: 3600,
},
});
Always fetch fresh data:
await fetch(url, {
cache: "no-store",
});
Next.js has built-in caching and revalidation, which helps improve performance.
11. Server Actions
Server Actions let you run server-side code directly from forms without creating API endpoints.
Create a Server Action:
"use server";
export async function createUser(
formData: FormData
) {
const name = formData.get("name");
// save to database
}
Use it inside a form:
<form action={createUser}>
<input name="name" />
<button>Create User</button>
</form>
This is now the recommended approach for many form submissions in the App Router.
12. Loading States
Create:
app/loading.tsx
Example:
export default function Loading() {
return <p>Loading...</p>;
}
Next.js automatically displays this while data is loading.
13. Error Handling
Create:
app/error.tsx
Example:
"use client";
export default function Error({
error,
reset,
}: {
error: Error;
reset: () => void;
}) {
return (
<button onClick={reset}>
Try Again
</button>
);
}
14. API Routes
Need an API?
Create:
app/api/users/route.ts
GET example:
export async function GET() {
return Response.json({
success: true,
});
}
POST example:
export async function POST(
request: Request
) {
const body = await request.json();
return Response.json(body);
}
15. Image Optimization
Use the built-in Image component:
import Image from "next/image";
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
/>
Benefits:
- Lazy loading
- Responsive images
- Better performance
- Automatic optimization
16. Fonts
Install fonts directly from Google Fonts:
import { Inter } from "next/font/google";
const inter = Inter({
subsets: ["latin"],
});
Apply globally:
<body className={inter.className}>
17. Environment Variables
Create:
DATABASE_URL=
NEXT_PUBLIC_API_URL=
Server only:
process.env.DATABASE_URL
Available on the client:
process.env.NEXT_PUBLIC_API_URL
Rule of thumb:
If the browser needs access to it, prefix it with
NEXT_PUBLIC_.
18. Production Build
Build your application:
npm run build
Run production mode:
npm run start
Check for production errors before deployment.
19. When Should I Use a Server Component?
Use a Server Component when:
- Fetching data
- Querying databases
- Accessing secrets
- Rendering static content
Example:
export default async function Products() {
const products = await getProducts();
return <div>{products.length}</div>;
}
20. When Should I Use a Client Component?
Use a Client Component when:
- Using state
- Using effects
- Handling clicks
- Accessing browser APIs
Example:
"use client";
import { useState } from "react";
export default function LikeButton() {
const [likes, setLikes] = useState(0);
return (
<button
onClick={() => setLikes(likes + 1)}
>
{likes}
</button>
);
}
Final Thoughts
When you're starting with Next.js, don't try to learn everything at once.
Focus on these four concepts first:
- Routing
- Server Components
- Client Components
- Data Fetching
Once those topics click, the rest of the framework starts making sense.
Bookmark this cheat sheet, keep building projects, and you'll be productive with Next.js much faster than you think.
And as always, Happy coding!

Top comments (0)