Build a Real Web App with React + Next.js
Step up from plain HTML files. Create a Next.js project, break the UI into reusable components, manage state with useState, and ship it to Vercel just like a real product team.
What you'll learn
- 1Create a Next.js project with create-next-app
- 2Write components in JSX and compose them
- 3Manage local component state with useState
- 4Add routing between pages using the App Router
- 5Deploy the app to Vercel β same flow as Lesson 1
1. Why React + Next.js?
- React turns the UI into reusable components β write once, use everywhere
- Next.js wraps React with routing, server features, and zero-config builds
- Together they are the most common stack for modern web apps
- Vercel was made by the Next.js team β deployment is one click
2. Set Up the Project
You need Node.js installed. Get the LTS version from https://nodejs.org.
node --version # v20.x or newer
npm --version
npx create-next-app@latest my-app
# β Use TypeScript? Yes
# β Use ESLint? Yes
# β Use Tailwind CSS? Yes (recommended for styling)
# β Use App Router? Yes
# β Use src/ directory? No
# β Customize import alias? No
cd my-app
npm run dev # open http://localhost:30003. Folder Tour
my-app/
βββ app/ # routes live here
β βββ layout.tsx # wraps every page (header, footer)
β βββ page.tsx # the homepage (/)
β βββ about/
β βββ page.tsx # /about
βββ public/ # static assets
βββ package.json
βββ tsconfig.jsonRoutes are just folders
- app/page.tsx β /
- app/about/page.tsx β /about
- app/blog/[slug]/page.tsx β /blog/anything (dynamic)
4. Your First Component
// app/page.tsx
export default function HomePage() {
return (
<main className="p-8">
<h1 className="text-3xl font-bold">Hello, Next.js!</h1>
<p className="text-gray-600">My first React component.</p>
</main>
);
}JSX looks like HTML inside JavaScript. Key differences: className instead of class, self-closing tags require /, expressions go in { }.
5. Components & Props
// app/components/Card.tsx
type CardProps = { title: string; description: string };
export default function Card({ title, description }: CardProps) {
return (
<div className="rounded-lg border p-4 shadow-sm">
<h2 className="text-xl font-semibold">{title}</h2>
<p className="text-gray-500">{description}</p>
</div>
);
}
// app/page.tsx
import Card from "./components/Card";
export default function Home() {
return (
<main className="p-8 grid gap-4 md:grid-cols-3">
<Card title="HTML" description="Structure" />
<Card title="CSS" description="Style" />
<Card title="JavaScript" description="Behavior" />
</main>
);
}6. State with useState
"use client"; // needed for hooks in App Router
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div className="text-center">
<p className="text-2xl">{count}</p>
<button onClick={() => setCount(count + 1)}
className="px-4 py-2 bg-blue-600 text-white rounded">
+ Increment
</button>
</div>
);
}App Router components are server components by default. Add "use client" at the top of files that use hooks like useState or useEffect.
7. Multiple Pages & Navigation
// app/about/page.tsx
export default function About() {
return <main className="p-8"><h1>About me</h1></main>;
}
// app/layout.tsx β header lives in the shared layout
import Link from "next/link";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<nav className="p-4 border-b flex gap-4">
<Link href="/">Home</Link>
<Link href="/about">About</Link>
</nav>
{children}
</body>
</html>
);
}Use <Link> from next/link instead of <a>. It enables fast client-side navigation without full page reloads.
8. Tailwind for Styling
Tailwind gives you styling via utility classes β no separate CSS file needed.
<button className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
Click me
</button>- px-4 py-2 β padding
- bg-blue-600 β background color
- text-white β text color
- rounded β border radius
- hover:bg-blue-700 β hover state
9. Deploy to Vercel
- Push the project to a new GitHub repo (git init / add / commit / push)
- Visit Vercel β Add New Project β import the repo
- Click Deploy β Vercel detects Next.js automatically
- Your app is live at https://my-app-your-name.vercel.app
Subsequent pushes redeploy automatically β exactly like Lesson 1.
10. What is Next
- You created a real Next.js project with TypeScript and Tailwind
- You built reusable components with props
- You managed state with useState
- You added routing and a shared layout
- You deployed everything to Vercel
From here on, the curriculum deepens each piece: HTML, CSS, JavaScript, then Node.js, databases, TypeScript, advanced React, and finally collaboration, accessibility, and security.
π Mini Projects
All lecture materials and example code are openly available on GitHub.
View on GitHub β