Next.js 14: The Complete Guide to React Framework
Next.js is the most popular React framework, powering applications for companies like Netflix, TikTok, and Twitch. It provides everything you need to build production-ready React apps with excellent developer experience.
Why Next.js?
Plain React challenges:
- Manual routing setup
- No built-in SSR/SSG
- Complex optimization
- No API routes
- Manual code splitting
Next.js solutions:
- File-based routing
- Built-in SSR, SSG, ISR
- Automatic optimization
- API routes included
- Automatic code splitting
Installation
```bash npx create-next-app@latest my-app cd my-app npm run dev ```
Your app runs at http://localhost:3000
File-Based Routing
The `app` directory structure defines routes:
``` app/ ├── page.tsx # / (homepage) ├── about/ │ └── page.tsx # /about ├── blog/ │ ├── page.tsx # /blog │ └── [slug]/ │ └── page.tsx # /blog/post-1 └── dashboard/ └── page.tsx # /dashboard ```
Creating pages:
```tsx // app/page.tsx export default function Home() { return
Homepage
; }// app/about/page.tsx export default function About() { return
About Us
; }// app/blog/[slug]/page.tsx export default function BlogPost({ params }: { params: { slug: string } }) { return
Post: {params.slug}
; } ```Layouts
Shared UI across routes:
```tsx // app/layout.tsx (root layout) export default function RootLayout({ children, }: { children: React.ReactNode; }) { return (
{children} ); }// app/dashboard/layout.tsx (nested layout) export default function DashboardLayout({ children, }: { children: React.ReactNode; }) { return (
Data Fetching
Server Components (Default)
Fetch data directly in components:
```tsx // app/posts/page.tsx async function getPosts() { const res = await fetch(‘https://api.example.com/posts’); return res.json(); }
export default async function PostsPage() { const posts = await getPosts();
return (
{post.title}
{post.excerpt}
Static Generation (SSG)
```tsx // app/blog/[slug]/page.tsx export async function generateStaticParams() { const posts = await fetch(‘https://api.example.com/posts’).then((res) => res.json() );
return posts.map((post) => ({ slug: post.slug, })); }
export default async function Post({ params }) { const post = await fetch(`https://api.example.com/posts/\${params.slug}\`).then( (res) => res.json() );
return (
{post.title}
Client Components
For interactivity:
```tsx ‘use client’;
import { useState } from ‘react’;
export default function Counter() { const [count, setCount] = useState(0);
return ( <button onClick={() => setCount(count + 1)}> Count: {count} ); } ```
API Routes
Create backend endpoints:
```tsx // app/api/hello/route.ts import { NextResponse } from ‘next/server’;
export async function GET() { return NextResponse.json({ message: ‘Hello World’ }); }
export async function POST(request: Request) { const body = await request.json(); return NextResponse.json({ received: body }); } ```
With database:
```tsx // app/api/posts/route.ts import { NextResponse } from ‘next/server’; import { db } from ’@/lib/db’;
export async function GET() { const posts = await db.post.findMany(); return NextResponse.json(posts); }
export async function POST(request: Request) { const body = await request.json(); const post = await db.post.create({ data: body, }); return NextResponse.json(post); } ```
Dynamic Routes
```tsx // app/blog/[slug]/page.tsx - Single dynamic segment // Matches: /blog/hello-world
// app/shop/[…slug]/page.tsx - Catch-all // Matches: /shop/a, /shop/a/b, /shop/a/b/c
// app/docs/[[…slug]]/page.tsx - Optional catch-all // Matches: /docs, /docs/a, /docs/a/b ```
Metadata
SEO optimization:
```tsx // Static metadata export const metadata = { title: ‘My App’, description: ‘Welcome to my app’, };
// Dynamic metadata export async function generateMetadata({ params }) { const post = await getPost(params.id);
return { title: post.title, description: post.excerpt, openGraph: { title: post.title, description: post.excerpt, images: [post.image], }, }; } ```
Image Optimization
```tsx import Image from ‘next/image’;
export default function ProfilePage() { return ( <Image src=“/profile.jpg” alt=“Profile” width={500} height={500} priority // Load immediately /> ); } ```
Navigation
```tsx import Link from ‘next/link’; import { useRouter } from ‘next/navigation’;
export default function Navigation() { const router = useRouter();
return (