Next.js: The 80-20 Guide#
A practical guide to building modern Next.js applications with App Router, Server Components, and Better Auth.
🎯 What You'll Learn#
- App Router - Modern Next.js routing with app directory
- Server Components - Server-side rendering and data fetching
- Client Components - Interactive UI with React hooks
- Better Auth - Complete authentication with login/signup
- API Routes - Build backend endpoints in Next.js
- TypeScript - Type-safe Next.js development
📚 Sections#
1. Getting Started#
Project setup, folder structure, and basic concepts.
2. Better Auth Setup#
Complete authentication setup with Better Auth.
3. Auth UI Components#
Login, signup, and protected page components.
🚀 Quick Start#
# Create Next.js app with TypeScript
npx create-next-app@latest my-app --typescript --app --tailwind
# Navigate to project
cd my-app
# Install Better Auth
npm install better-auth
# Run development server
npm run dev
Visit http://localhost:3000
📁 Project Structure#
my-app/
├── app/
│ ├── (auth)/
│ │ ├── login/
│ │ │ └── page.tsx
│ │ └── signup/
│ │ └── page.tsx
│ ├── (protected)/
│ │ ├── dashboard/
│ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── api/
│ │ ├── auth/
│ │ │ └── [...all]/route.ts
│ │ └── users/
│ │ └── route.ts
│ ├── layout.tsx
│ └── page.tsx
├── components/
│ ├── ui/
│ ├── auth/
│ └── shared/
├── lib/
│ ├── auth.ts
│ └── db.ts
└── types/
└── auth.ts
🎓 Core Concepts#
App Router vs Pages Router#
App Router (Modern, Recommended):
- Uses app/ directory
- Server Components by default
- File-based routing with folders
- Built-in layouts and loading states
Pages Router (Legacy):
- Uses pages/ directory
- Client components by default
- File-based routing with files
Server vs Client Components#
Server Components (Default):
// app/page.tsx - Server Component
export default async function Page() {
const data = await fetch('...');
return <div>{data}</div>;
}
Client Components (Use 'use client'):
'use client'
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
Routing Files#
app/
├── page.tsx → /
├── about/
│ └── page.tsx → /about
├── blog/
│ ├── page.tsx → /blog
│ └── [slug]/
│ └── page.tsx → /blog/:slug
└── layout.tsx → Wraps all pages
⚡ Key Features#
Server-Side Data Fetching#
async function getUsers() {
const res = await fetch('https://api.example.com/users');
return res.json();
}
export default async function UsersPage() {
const users = await getUsers();
return <UserList users={users} />;
}
Dynamic Routes#
// app/blog/[slug]/page.tsx
export default function BlogPost({ params }: { params: { slug: string } }) {
return <h1>Post: {params.slug}</h1>;
}
Loading States#
// app/loading.tsx
export default function Loading() {
return <div>Loading...</div>;
}
Error Handling#
// app/error.tsx
'use client'
export default function Error({ error, reset }: {
error: Error;
reset: () => void;
}) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={reset}>Try again</button>
</div>
);
}
🔐 Authentication Overview#
Better Auth provides: - ✅ Email/password authentication - ✅ OAuth providers (Google, GitHub, etc.) - ✅ Session management - ✅ Protected routes - ✅ Type-safe API
// lib/auth.ts
import { betterAuth } from "better-auth";
export const auth = betterAuth({
database: {
/* ... */
},
emailAndPassword: {
enabled: true,
},
});
// app/api/auth/[...all]/route.ts
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";
export const { GET, POST } = toNextJsHandler(auth);
📖 Best Practices#
- ✅ Use Server Components by default - Only add 'use client' when needed
- ✅ Group routes with folders - Use (auth), (protected) for organization
- ✅ Co-locate components - Keep components near where they're used
- ✅ Use TypeScript - Full type safety with Next.js
- ✅ Leverage caching - Next.js caches fetch requests by default
- ✅ Optimize images - Use next/image for automatic optimization
🛠️ Essential Packages#
# Authentication
npm install better-auth
# UI Components (optional)
npm install @radix-ui/react-dialog
npm install class-variance-authority clsx tailwind-merge
# Form handling
npm install react-hook-form zod @hookform/resolvers
# State management (if needed)
npm install zustand
Next Steps#
Start with Getting Started to set up your Next.js project, then follow through each section to build a complete authenticated application.
Pro Tip: Next.js 14+ uses Server Components by default. This means you can fetch data directly in your components without useEffect or loading states!