All Articles
Tutorial10 min read

Next.js 14: Complete Guide for React Developers

Master Next.js 14 with App Router. Server Components, data fetching, caching, and deployment patterns explained with examples.

T

TechGyanic

December 4, 2025

Next.js 14: Complete Guide for React Developers

Moving from Create React App to Next.js felt like upgrading from a bicycle to a motorcycle. More power, but also more things that can go wrong. Here's everything I learned.

Why Next.js?

  • Server-Side Rendering - Better SEO, faster initial load
  • File-based routing - No react-router configuration
  • API routes - Backend in the same project
  • Built-in optimization - Images, fonts, scripts

App Router vs Pages Router

Next.js 14 uses the App Router by default. Key differences:

pages/              →  app/
pages/index.js      →  app/page.js
pages/about.js      →  app/about/page.js
pages/blog/[slug].js → app/blog/[slug]/page.js

Server vs Client Components

Server Components (default in App Router):

  • Run on server
  • Can access database directly
  • Smaller bundle size
  • No interactivity

Client Components:

  • Run in browser
  • Needed for interactivity
  • Use "use client" directive
// Server Component (default)
async function ProductList() {
  const products = await db.products.findMany();
  
  return (
    <ul>
      {products.map(p => <li key={p.id}>{p.name}</li>)}
    </ul>
  );
}

// Client Component
"use client"
function AddToCartButton({ productId }) {
  const [loading, setLoading] = useState(false);
  
  const handleClick = async () => {
    setLoading(true);
    await addToCart(productId);
    setLoading(false);
  };
  
  return <button onClick={handleClick} disabled={loading}>Add to Cart</button>;
}

Data Fetching

In Server Components

// No useEffect needed!
async function UserProfile({ userId }) {
  const user = await fetch(`/api/users/${userId}`);
  return <h1>{user.name}</h1>;
}

Caching

// Cached (default)
fetch('https://api.example.com/data');

// Revalidate every 60 seconds
fetch('https://api.example.com/data', { next: { revalidate: 60 } });

// No cache
fetch('https://api.example.com/data', { cache: 'no-store' });

API Routes

// app/api/users/route.js
import { NextResponse } from 'next/server';

export async function GET(request) {
  const users = await db.users.findMany();
  return NextResponse.json(users);
}

export async function POST(request) {
  const body = await request.json();
  const user = await db.users.create({ data: body });
  return NextResponse.json(user, { status: 201 });
}

Layouts and Templates

// app/layout.js - Wraps entire app
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Navbar />
        {children}
        <Footer />
      </body>
    </html>
  );
}

// app/dashboard/layout.js - Nested layout
export default function DashboardLayout({ children }) {
  return (
    <div className="dashboard">
      <Sidebar />
      <main>{children}</main>
    </div>
  );
}

Loading and Error States

// app/products/loading.js
export default function Loading() {
  return <ProductSkeleton />;
}

// app/products/error.js
"use client"
export default function Error({ error, reset }) {
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={reset}>Try again</button>
    </div>
  );
}

Metadata for SEO

// app/blog/[slug]/page.js
export async function generateMetadata({ params }) {
  const post = await getPost(params.slug);
  
  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      images: [post.coverImage],
    },
  };
}

Deployment

Vercel (best experience):

npm install -g vercel
vercel

Self-hosted:

npm run build
npm start

Common Gotchas

  1. Client/Server boundary - You'll forget "use client" a lot
  2. Hydration errors - Server and client must render same HTML
  3. Fetch caching - Aggressive by default, can cause stale data

Next.js has a learning curve, but the developer experience and performance benefits are worth it.

nextjsreactfrontendjavascriptweb-development
Share this article
T

Written by

TechGyanic

Sharing insights on technology, software architecture, and development best practices.