Skip to content

developer-junaid/nextjs-16-crash-course

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“š Next.js 16 Reference Guide

A comprehensive reference for Next.js 16 concepts with working examples. Use this as a boilerplate or quick lookup for common patterns.

Stack: Next.js 16.1.1 β€’ React 19 β€’ TypeScript β€’ Tailwind CSS 4

🎬 Learned from: Next.js 16 Crash Course on YouTube


πŸ“‘ Table of Contents


πŸš€ Quick Start

# Install dependencies
npm install

# Run development server (with Turbopack)
npm run dev

# Build for production
npm run build

# Start production server
npm start

πŸ“ Project Structure

app/
β”œβ”€β”€ layout.tsx              # Root layout (required)
β”œβ”€β”€ globals.css             # Global styles
β”œβ”€β”€ loader.tsx              # Loading UI component
β”œβ”€β”€ error.tsx               # Error boundary
β”œβ”€β”€ global-error.tsx        # Global error boundary
β”‚
β”œβ”€β”€ (root)/                 # Route group with Navbar/Footer layout
β”‚   β”œβ”€β”€ layout.tsx          # β†’ Wraps: Navbar + {children} + Footer
β”‚   β”œβ”€β”€ page.tsx            # β†’ /
β”‚   β”œβ”€β”€ about/page.tsx      # β†’ /about (throws error for demo)
β”‚   β”œβ”€β”€ books/page.tsx      # β†’ /books (fetches from API)
β”‚   └── client-fetcher/     # β†’ /client-fetcher
β”‚       └── page.tsx
β”‚
β”œβ”€β”€ (dashboard)/            # Route group with Sidebar layout
β”‚   β”œβ”€β”€ layout.tsx          # β†’ Wraps: Sidebar + {children}
β”‚   └── dashboard/page.tsx  # β†’ /dashboard
β”‚
└── api/                    # API routes
    β”œβ”€β”€ route.ts            # β†’ GET /api
    β”œβ”€β”€ db.ts               # Mock database
    └── books/
        β”œβ”€β”€ route.ts        # β†’ GET, POST /api/books
        └── [id]/route.ts   # β†’ PUT, DELETE /api/books/:id

components/
β”œβ”€β”€ hello.tsx               # Client component example
β”œβ”€β”€ clientDataFetcher.tsx   # Client-side data fetching
└── dataFetcher.tsx         # Server component data fetching

🧠 Core Concepts

Server vs Client Components

Aspect Server Components Client Components
Rendering Server β†’ sends HTML Browser
Directive Default (none needed) 'use client' at top
Use for Data fetching, secrets, DB access Interactivity, forms, events
Best practice Use by default Use only when needed

πŸ“ Examples:

// Server Component (default)
const ServerPage = () => {
  console.log("Runs on server"); // Check terminal
  return <div>Hello</div>;
};

// Client Component
("use client");
const ClientComponent = () => {
  console.log("Runs on browser"); // Check browser console
  return <button onClick={() => alert("Hi")}>Click</button>;
};

πŸ’‘ Rule: Use Server Components until you need client interactivity and get an error.


Route Groups & Layouts

Route groups (folder) organize routes without affecting URL and allow different layouts.

File URL Layout
app/(root)/page.tsx / Navbar + Footer
app/(root)/about/page.tsx /about Navbar + Footer
app/(dashboard)/dashboard/page.tsx /dashboard Sidebar

πŸ“ Files:

⚠️ You must keep a root layout.tsx in /app directory.


Error Handling

File Scope Location
error.tsx Catches errors in that route segment app/(root)/error.tsx
global-error.tsx Catches root layout errors app/global-error.tsx
"use client"; // Required!

const Error = ({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) => {
  return (
    <div>
      <h1>Something went wrong!</h1>
      <button onClick={reset}>Try again</button>
    </div>
  );
};

πŸ“ Test it: Visit /about to see error boundary in action.


Loading UI

Create loading.tsx for automatic loading states during navigation/data fetching.

πŸ“ Example: app/loader.tsx

const Loading = () => <div>Loading...</div>;
export default Loading;

Also supports: unauthorized.tsx and forbidden.tsx for auth states.


πŸ“‘ Data Fetching

Client-Side (useEffect)

Traditional React approach - renders loading state first, then fetches.

πŸ“ File: components/clientDataFetcher.tsx

"use client";
import { useEffect, useState } from "react";

const ClientDataFetcher = () => {
  const [data, setData] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const res = await fetch("https://api.example.com/data");
      setData(await res.json());
    };
    fetchData();
  }, []);

  return <div>{/* render data */}</div>;
};

Server Components (Recommended)

Next.js recommended approach - fetches data on server, sends complete HTML.

πŸ“ File: components/dataFetcher.tsx

const DataFetcher = async () => {
  const res = await fetch("https://api.example.com/data");
  if (!res.ok) throw new Error("Failed to fetch");
  const data = await res.json();

  return <div>{/* render data */}</div>;
};

βœ… Benefits:

Benefit Description
Better SEO Content rendered on server
Reduced FCP Faster First Contentful Paint
Fewer lines No useState/useEffect boilerplate
Security API keys stay on server
Deduplication Same requests are automatically deduped
No waterfall Requests can be parallelized
HMR Cache Cached to reduce build-time API calls

πŸ”Œ API Routes

Basic Route

Create route.ts in any folder under /app to create an API endpoint.

πŸ“ File: app/api/route.ts β†’ GET /api

export async function GET(request: Request) {
  return Response.json({ message: "Hello World!" });
}

CRUD Operations

πŸ“ File: app/api/books/route.ts

// GET /api/books
export async function GET(request: Request) {
  return Response.json(books);
}

// POST /api/books
export async function POST(request: Request) {
  const book = await request.json();
  books.push(book);
  return Response.json(book);
}

Dynamic Routes

Use [param] folder syntax for dynamic segments.

πŸ“ File: app/api/books/[id]/route.ts

// PUT /api/books/:id
export async function PUT(
  request: Request,
  context: { params: { id: string } }
) {
  const id = +context.params.id;
  const book = await request.json();
  // Update logic...
  return Response.json(book);
}

// DELETE /api/books/:id
export async function DELETE(
  request: Request,
  context: { params: { id: string } }
) {
  const id = +context.params.id;
  // Delete logic...
  return Response.json({ success: true });
}

πŸ“ Test endpoints:

  • GET /api/books - List all books
  • POST /api/books - Create book
  • PUT /api/books/1 - Update book
  • DELETE /api/books/1 - Delete book

πŸ’Ύ Caching Strategies

Cache Types

Type What it does
Browser Cache Saves static files locally
Server Cache Stores pre-rendered pages & API responses
Data Cache Remembers fetched data to avoid repeat requests

Rendering Strategies (Auto-decided by Next.js)

Strategy Description
SSG Static Site Generation - HTML at build time
ISR Incremental Static Regeneration - updates static pages post-deploy
PPR Partial Pre-Rendering - mix of static + dynamic components

use cache Directive

Mark components, routes, or functions to cache their output.

"use cache";

async function CachedComponent() {
  const data = await fetchData(); // Cached!
  return <div>{data}</div>;
}

Behavior:

  • Pre-renders at build time
  • Stores in memory
  • Auto-revalidates every 15 minutes (default)

Cache Configuration

Enable in next.config.ts:

const nextConfig = {
  cacheComponents: true, // Enable component caching
};

Custom cache lifetime:

import { cacheLife, cacheTag } from "next/cache";

async function getData() {
  "use cache";
  cacheLife("twoweeks"); // How long to cache
  cacheTag("products"); // Tag for targeted revalidation

  return await fetchProducts();
}

Define custom cache profiles in next.config.ts:

const nextConfig = {
  cacheLife: {
    twoweeks: {
      stale: 60 * 5, // Serve stale for 5 min
      revalidate: 60 * 60 * 24 * 14, // Revalidate after 2 weeks
      expire: 60 * 60 * 24 * 365, // Expire after 1 year
    },
  },
};

Manual revalidation:

import { revalidateTag, revalidatePath } from "next/cache";

// Revalidate by tag
revalidateTag("products");

// Revalidate by path
revalidatePath("/products");
Function Purpose
cacheLife() Controls when to clear cache
cacheTag() Controls what to clear (targeted)
revalidateTag() Manually refresh tagged cache
revalidatePath() Manually refresh path cache

🏷️ Metadata & SEO

1. Static Metadata (Config-based)

Export metadata object for pages with fixed SEO data.

export const metadata = {
  title: "Home | My App",
  description: "Welcome to my application",
  openGraph: {
    title: "Home",
    images: ["/og-image.png"],
  },
};

2. Dynamic Metadata (Content-based)

Use generateMetadata for dynamic pages (e.g., blog posts).

export async function generateMetadata({ params }: { params: { id: string } }) {
  const post = await getPost(params.id);

  return {
    title: `${post.title} | My Blog`,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [post.image],
    },
    twitter: {
      title: post.title,
      description: post.excerpt,
      images: [post.image],
    },
  };
}

3. File-Based Metadata

Place these files in /app for automatic SEO:

File Purpose
robots.txt Search engine crawling rules
sitemap.xml Site structure for search engines
favicon.ico Browser tab icon
icon.png App icon
apple-icon.png iOS home screen icon
opengraph-image.png Social sharing preview
twitter-image.png Twitter card image

robots.txt:

User-Agent: *
Allow: /
Disallow: /private/
Sitemap: https://example.com/sitemap.xml

sitemap.xml:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com</loc>
    <lastmod>2024-01-01</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1</priority>
  </url>
</urlset>

πŸ“ Reference images: Check /public/meta-*.png for icon conventions.


⚑ Performance Features

Turbopack

Rust-based bundler for faster development compilation.

# Enabled by default in Next.js 16
npm run dev

πŸ“ Config: next.config.ts

experimental: {
  turbopackFileSystemCacheForDev: true,  // Extra caching
}

React Compiler

Automatically optimizes React code at build time (auto-memoization).

Setup:

npm install babel-plugin-react-compiler@latest

πŸ“ Config: next.config.ts

const nextConfig = {
  reactCompiler: true,
};

πŸ”§ Build Adapters (Alpha)

Adapters let hosting providers customize the build pipeline.

Benefits:

  • βœ… Zero-config deployments
  • βœ… Environment-specific optimizations
  • βœ… Freedom from vendor lock-in

Capabilities:

  • Modify Next.js config at build time
  • Optimize final build output
  • Adjust runtime behavior

πŸ“– Quick Reference

Concept File Pattern Example
Page page.tsx app/about/page.tsx β†’ /about
Layout layout.tsx Wraps children routes
Loading loading.tsx Suspense fallback
Error error.tsx Error boundary
Route Group (folder) (dashboard)/ - no URL impact
Dynamic Route [param] [id]/page.tsx β†’ /123
API Route route.ts app/api/users/route.ts
Catch-all [...slug] app/docs/[...slug]/page.tsx
Optional Catch-all [[...slug]] Matches with or without params

πŸ”— Useful Links


Built for learning and quick reference πŸš€

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors