Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
menu
  1. Home
  2. /Web Development
  3. /Nextjs
  4. /Pathname Searchparams Hooks
Your Progress0%
0 of 70 completed

NextJS Topics

Getting Started

  • What is Next.js?
  • Next.js vs React - Key Differences
  • Creating Your First Next.js 15 Project
  • Next.js Project Structure Explained
  • App Router vs Pages Router

Routing Fundamentals

  • File-Based Routing Basics
  • Creating Pages with page.tsx
  • Dynamic Routes and Route Parameters
  • Catch-All and Optional Catch-All Routes
  • Route Groups for Organization
  • Parallel Routes
  • Intercepting Routes

Layouts and Pages

  • Understanding Layouts
  • Root Layout and Global Configuration
  • Nested Layouts
  • Templates vs Layouts
  • Loading States with loading.tsx
  • Error Handling with error.tsx

Server and Client Components

  • Understanding Server Components
  • Client Components with 'use client'
  • When to Use Server vs Client Components
  • Component Composition Patterns
  • Passing Props Between Server and Client
  • Server Component Patterns and Best Practices

Data Fetching

  • Fetching Data in Server Components
  • Parallel and Sequential Data Fetching
  • Data Fetching Patterns and Strategies
  • Caching and Revalidation
  • Revalidate and Cache Tags
  • Handling Loading and Error States in Data Fetching

Navigation and Links

  • Link Component Basics
  • useRouter Hook for Programmatic Navigation
  • usePathname and useSearchParams Hooks
  • Active Links and Navigation States
  • Redirects and Navigation Guards

Styling in Next.js

  • CSS Modules in Next.js
  • Tailwind CSS Setup and Configuration
  • Global Styles and CSS Variables
  • Next.js Font Optimization

Images and Media

  • Next.js Image Component Basics
  • Image Optimization and Best Practices
  • Working with Static Assets

Forms and Data Mutations

  • Understanding Server Actions
  • Form Handling with Server Actions
  • Form Validation and Error Handling
  • useFormStatus and useFormState Hooks
  • Revalidating Data After Mutations
  • Optimistic Updates

Metadata and SEO

  • Static Metadata Configuration
  • Dynamic Metadata Generation
  • Open Graph and Social Media Cards
  • Sitemap and Robots.txt

API Routes and Route Handlers

  • Route Handlers Introduction
  • GET and POST Request Handlers
  • Dynamic API Routes
  • Request and Response Objects
  • API Error Handling and Status Codes

Middleware and Advanced Features

  • Introduction to Middleware
  • Authentication with Middleware
  • Environment Variables and Configuration
  • Streaming and Suspense
  • Not Found and Global Error Pages

Deployment and Optimization

  • Understanding Static and Dynamic Rendering
  • generateStaticParams for Static Generation
  • Build and Production Optimization
  • Deploying to Vercel
  • Alternative Deployment Options
  • Performance Monitoring and Analytics

Real-World Projects

  • Project 1: E-commerce Product Catalog
  • Project 2: Dashboard with Authentication

usePathname and useSearchParams Hooks

Reading current route and query parameters in Client Components

Building dynamic navigation requires knowing where users are in your application. The usePathname hook tells you the current route path, while useSearchParams gives you access to URL query parameters. Together, these hooks enable you to highlight active links, build dynamic breadcrumbs, read filters from URLs, and create navigation UI that responds to the current route. Let's master reading and working with URL state!

usePathname Hook

The usePathname hook returns the current pathname:

Basic Usage

components/CurrentPath.tsx
'use client';

import { usePathname } from 'next/navigation';

export function CurrentPath() {
  const pathname = usePathname();

  return (
    <div className="p-4 bg-gray-100 rounded">
      <p className="text-sm text-gray-600">Current path:</p>
      <p className="font-mono font-bold">{pathname}</p>
    </div>
  );
}

// URL: https://example.com/blog/my-post?sort=recent
// pathname: "/blog/my-post"

// URL: https://example.com/products
// pathname: "/products"

// URL: https://example.com/
// pathname: "/"

// ✅ Returns just the pathname
// ✅ No query parameters
// ✅ No domain or protocol
// ✅ No hash fragment

Conditional Rendering Based on Path

components/ConditionalNav.tsx
'use client';

import { usePathname } from 'next/navigation';

export function ConditionalNav() {
  const pathname = usePathname();

  // Show different nav for different sections
  const isHome = pathname === '/';
  const isBlog = pathname.startsWith('/blog');
  const isAdmin = pathname.startsWith('/admin');

  if (isAdmin) {
    return <AdminNav />;
  }

  if (isBlog) {
    return <BlogNav />;
  }

  return <MainNav />;
}

// ✅ Different navigation for different sections
// ✅ Check exact path with ===
// ✅ Check path prefix with startsWith()

Dynamic Breadcrumbs

components/Breadcrumbs.tsx
'use client';

import { usePathname } from 'next/navigation';
import Link from 'next/link';

export function Breadcrumbs() {
  const pathname = usePathname();

  // Split path into segments
  const segments = pathname.split('/').filter(Boolean);

  // Build breadcrumb items
  const breadcrumbs = segments.map((segment, index) => {
    const href = '/' + segments.slice(0, index + 1).join('/');
    const label = segment
      .split('-')
      .map(word => word.charAt(0).toUpperCase() + word.slice(1))
      .join(' ');

    return { href, label };
  });

  return (
    <nav className="flex items-center gap-2 text-sm mb-6">
      <Link 
        href="/"
        className="text-gray-600 hover:text-blue-600 transition"
      >
        Home
      </Link>

      {breadcrumbs.map((crumb, index) => {
        const isLast = index === breadcrumbs.length - 1;

        return (
          <div key={crumb.href} className="flex items-center gap-2">
            <span className="text-gray-400">/</span>
            {isLast ? (
              <span className="text-gray-900 font-semibold">
                {crumb.label}
              </span>
            ) : (
              <Link
                href={crumb.href}
                className="text-gray-600 hover:text-blue-600 transition"
              >
                {crumb.label}
              </Link>
            )}
          </div>
        );
      })}
    </nav>
  );
}

// URL: /blog/tech/nextjs-tutorial
// Breadcrumbs: Home / Blog / Tech / Nextjs Tutorial
//              ^     ^      ^     ^
//              /    /blog  /blog/tech  /blog/tech/nextjs-tutorial

// ✅ Automatically generates breadcrumbs from path
// ✅ Each segment is clickable (except last)
// ✅ Formats segment names nicely

usePathname vs Server Component params

Server Components receive the pathname via props. Only use usePathname in Client Components:

TYPESCRIPT
// Server Component - use props
async function ServerPage({ params }: { params: { slug: string } }) {
  const slug = params.slug; // From route parameters
  return <div>{slug}</div>;
}

// Client Component - use usePathname
'use client';
function ClientComponent() {
  const pathname = usePathname(); // From hook
  return <div>{pathname}</div>;
}

useSearchParams Hook

The useSearchParams hook returns a read-only URLSearchParams object:

Basic Usage

components/SearchParamsDisplay.tsx
'use client';

import { useSearchParams } from 'next/navigation';

export function SearchParamsDisplay() {
  const searchParams = useSearchParams();

  // Get specific parameter
  const query = searchParams.get('q');
  const category = searchParams.get('category');
  const page = searchParams.get('page');

  return (
    <div className="p-4 bg-gray-100 rounded space-y-2">
      <p><strong>Query:</strong> {query || 'None'}</p>
      <p><strong>Category:</strong> {category || 'None'}</p>
      <p><strong>Page:</strong> {page || '1'}</p>
    </div>
  );
}

// URL: /search?q=nextjs&category=tutorials&page=2
// query: "nextjs"
// category: "tutorials"
// page: "2"

// URL: /search
// query: null
// category: null
// page: null

// ✅ Get individual parameters with .get()
// ✅ Returns null if parameter doesn't exist
// ✅ All values are strings

Common SearchParams Methods

TYPESCRIPT
'use client';

import { useSearchParams } from 'next/navigation';

export function SearchParamsExample() {
  const searchParams = useSearchParams();

  // Get single value
  const sort = searchParams.get('sort');
  // ?sort=recent → "recent"

  // Get all values for parameter (for arrays)
  const tags = searchParams.getAll('tag');
  // ?tag=react&tag=nextjs → ["react", "nextjs"]

  // Check if parameter exists
  const hasFilter = searchParams.has('filter');
  // ?filter=active → true
  // ?other=value → false

  // Get all parameters as object
  const allParams = Object.fromEntries(searchParams.entries());
  // ?sort=recent&page=2 → { sort: "recent", page: "2" }

  // Convert to string
  const queryString = searchParams.toString();
  // ?sort=recent&page=2 → "sort=recent&page=2"

  return (
    <div>
      <p>Sort: {sort}</p>
      <p>Tags: {tags.join(', ')}</p>
      <p>Has filter: {hasFilter ? 'Yes' : 'No'}</p>
      <p>All params: {JSON.stringify(allParams)}</p>
      <p>Query string: {queryString}</p>
    </div>
  );
}

// ✅ .get(key) - get single value
// ✅ .getAll(key) - get array of values
// ✅ .has(key) - check if exists
// ✅ .entries() - get all as entries
// ✅ .toString() - convert to query string

Suspense Boundary Requirement

app/search/page.tsx
import { Suspense } from 'react';

// Component that uses useSearchParams
function SearchResults() {
  'use client';
  
  const searchParams = useSearchParams();
  const query = searchParams.get('q');

  return <div>Results for: {query}</div>;
}

// Page must wrap in Suspense
export default function SearchPage() {
  return (
    <div>
      <h1>Search</h1>
      
      {/* Wrap useSearchParams components in Suspense */}
      <Suspense fallback={<div>Loading...</div>}>
        <SearchResults />
      </Suspense>
    </div>
  );
}

// ✅ Prevents entire page from client-side rendering
// ✅ Better performance
// ✅ Allows streaming

// ⚠️ Without Suspense:
// - Component de-opts to client-side rendering
// - Hurts performance
// - No streaming

⚠️ SearchParams are Read-Only

useSearchParams returns a read-only URLSearchParams. To update parameters, use useRouter:

TYPESCRIPT
'use client';

import { useSearchParams, useRouter } from 'next/navigation';

function FilterButton() {
  const searchParams = useSearchParams();
  const router = useRouter();

  const updateFilter = (filter: string) => {
    // Create new URLSearchParams
    const params = new URLSearchParams(searchParams.toString());
    params.set('filter', filter);
    
    // Navigate with new params
    router.push(`?${params.toString()}`);
  };

  return (
    <button onClick={() => updateFilter('active')}>
      Filter Active
    </button>
  );
}

Practical Examples

Example 1: Active Navigation Links

components/ActiveLink.tsx
'use client';

import { usePathname } from 'next/navigation';
import Link from 'next/link';

interface ActiveLinkProps {
  href: string;
  children: React.ReactNode;
}

export function ActiveLink({ href, children }: ActiveLinkProps) {
  const pathname = usePathname();
  const isActive = pathname === href || pathname.startsWith(href + '/');

  return (
    <Link
      href={href}
      className={`px-4 py-2 rounded-lg transition ${
        isActive
          ? 'bg-blue-600 text-white font-semibold'
          : 'text-gray-700 hover:bg-gray-100'
      }`}
    >
      {children}
    </Link>
  );
}

// Usage in navigation
export function Navigation() {
  return (
    <nav className="flex gap-2">
      <ActiveLink href="/">Home</ActiveLink>
      <ActiveLink href="/blog">Blog</ActiveLink>
      <ActiveLink href="/about">About</ActiveLink>
      <ActiveLink href="/contact">Contact</ActiveLink>
    </nav>
  );
}

// ✅ Active link is highlighted
// ✅ Works with nested routes (/blog/post-1 highlights /blog)
// ✅ Visual feedback for current page

Example 2: Search Filters with URL State

components/SearchFilters.tsx
'use client';

import { useSearchParams, useRouter } from 'next/navigation';
import { useCallback } from 'react';

export function SearchFilters() {
  const searchParams = useSearchParams();
  const router = useRouter();

  // Get current values
  const currentCategory = searchParams.get('category') || 'all';
  const currentSort = searchParams.get('sort') || 'recent';

  // Update filter function
  const updateFilter = useCallback((key: string, value: string) => {
    const params = new URLSearchParams(searchParams.toString());
    
    if (value === 'all') {
      params.delete(key);
    } else {
      params.set(key, value);
    }
    
    router.push(`?${params.toString()}`, { scroll: false });
  }, [searchParams, router]);

  return (
    <div className="space-y-4 p-4 bg-white rounded-lg shadow">
      {/* Category Filter */}
      <div>
        <label className="block text-sm font-medium mb-2">
          Category
        </label>
        <select
          value={currentCategory}
          onChange={(e) => updateFilter('category', e.target.value)}
          className="w-full px-3 py-2 border rounded-lg"
        >
          <option value="all">All Categories</option>
          <option value="tech">Tech</option>
          <option value="design">Design</option>
          <option value="business">Business</option>
        </select>
      </div>

      {/* Sort Filter */}
      <div>
        <label className="block text-sm font-medium mb-2">
          Sort By
        </label>
        <select
          value={currentSort}
          onChange={(e) => updateFilter('sort', e.target.value)}
          className="w-full px-3 py-2 border rounded-lg"
        >
          <option value="recent">Most Recent</option>
          <option value="popular">Most Popular</option>
          <option value="title">Title (A-Z)</option>
        </select>
      </div>

      {/* Clear Filters */}
      {(currentCategory !== 'all' || currentSort !== 'recent') && (
        <button
          onClick={() => router.push(window.location.pathname)}
          className="w-full px-4 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300"
        >
          Clear Filters
        </button>
      )}
    </div>
  );
}

// URL updates: /blog?category=tech&sort=popular
// ✅ Filters stored in URL
// ✅ Shareable URLs
// ✅ Browser back/forward works
// ✅ Preserves scroll position (scroll: false)

Example 3: Pagination with Search Params

components/Pagination.tsx
'use client';

import { useSearchParams, useRouter } from 'next/navigation';

interface PaginationProps {
  totalPages: number;
}

export function Pagination({ totalPages }: PaginationProps) {
  const searchParams = useSearchParams();
  const router = useRouter();

  const currentPage = Number(searchParams.get('page')) || 1;

  const goToPage = (page: number) => {
    const params = new URLSearchParams(searchParams.toString());
    params.set('page', page.toString());
    router.push(`?${params.toString()}`);
  };

  const pages = Array.from({ length: totalPages }, (_, i) => i + 1);

  return (
    <div className="flex items-center justify-center gap-2">
      {/* Previous Button */}
      <button
        onClick={() => goToPage(currentPage - 1)}
        disabled={currentPage === 1}
        className="px-4 py-2 border rounded-lg disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-100"
      >
        ← Previous
      </button>

      {/* Page Numbers */}
      {pages.map(page => {
        // Show first, last, current, and adjacent pages
        if (
          page === 1 ||
          page === totalPages ||
          (page >= currentPage - 1 && page <= currentPage + 1)
        ) {
          return (
            <button
              key={page}
              onClick={() => goToPage(page)}
              className={`px-4 py-2 border rounded-lg ${
                page === currentPage
                  ? 'bg-blue-600 text-white'
                  : 'hover:bg-gray-100'
              }`}
            >
              {page}
            </button>
          );
        }

        // Show ellipsis
        if (page === currentPage - 2 || page === currentPage + 2) {
          return <span key={page} className="px-2">...</span>;
        }

        return null;
      })}

      {/* Next Button */}
      <button
        onClick={() => goToPage(currentPage + 1)}
        disabled={currentPage === totalPages}
        className="px-4 py-2 border rounded-lg disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-100"
      >
        Next →
      </button>
    </div>
  );
}

// URL: /blog?page=3
// ✅ Page stored in URL
// ✅ Shareable links to specific pages
// ✅ Browser back/forward works
// ✅ Smart ellipsis for many pages

Example 4: Multi-Select Filters

components/TagFilter.tsx
'use client';

import { useSearchParams, useRouter } from 'next/navigation';

const AVAILABLE_TAGS = ['react', 'nextjs', 'typescript', 'tailwind', 'node'];

export function TagFilter() {
  const searchParams = useSearchParams();
  const router = useRouter();

  // Get current tags from URL
  const selectedTags = searchParams.getAll('tag');

  const toggleTag = (tag: string) => {
    const params = new URLSearchParams(searchParams.toString());
    
    if (selectedTags.includes(tag)) {
      // Remove tag - need to rebuild params without this tag
      params.delete('tag');
      selectedTags
        .filter(t => t !== tag)
        .forEach(t => params.append('tag', t));
    } else {
      // Add tag
      params.append('tag', tag);
    }
    
    router.push(`?${params.toString()}`, { scroll: false });
  };

  return (
    <div className="space-y-3">
      <h3 className="font-semibold">Filter by Tags</h3>
      
      <div className="flex flex-wrap gap-2">
        {AVAILABLE_TAGS.map(tag => {
          const isSelected = selectedTags.includes(tag);
          
          return (
            <button
              key={tag}
              onClick={() => toggleTag(tag)}
              className={`px-4 py-2 rounded-lg border transition ${
                isSelected
                  ? 'bg-blue-600 text-white border-blue-600'
                  : 'bg-white text-gray-700 border-gray-300 hover:border-blue-600'
              }`}
            >
              {tag}
              {isSelected && ' ✓'}
            </button>
          );
        })}
      </div>

      {selectedTags.length > 0 && (
        <div className="flex items-center gap-2">
          <span className="text-sm text-gray-600">
            {selectedTags.length} tag{selectedTags.length !== 1 ? 's' : ''} selected
          </span>
          <button
            onClick={() => router.push(window.location.pathname)}
            className="text-sm text-blue-600 hover:underline"
          >
            Clear all
          </button>
        </div>
      )}
    </div>
  );
}

// URL: /blog?tag=react&tag=nextjs&tag=typescript
// ✅ Multiple values for same parameter
// ✅ Toggle on/off
// ✅ Visual feedback
// ✅ Clear all option

Pathname and SearchParams Examples

Project structure with usePathname and useSearchParams patterns

appImportant

Select a file or folder to see details

Combining Pathname and SearchParams

components/SmartBreadcrumbs.tsx
'use client';

import { usePathname, useSearchParams } from 'next/navigation';
import Link from 'next/link';

export function SmartBreadcrumbs() {
  const pathname = usePathname();
  const searchParams = useSearchParams();

  const segments = pathname.split('/').filter(Boolean);
  
  // Build breadcrumbs with current filters
  const currentParams = searchParams.toString();
  const paramsString = currentParams ? `?${currentParams}` : '';

  const breadcrumbs = segments.map((segment, index) => {
    const href = '/' + segments.slice(0, index + 1).join('/');
    const label = segment
      .split('-')
      .map(word => word.charAt(0).toUpperCase() + word.slice(1))
      .join(' ');

    return { href, label };
  });

  return (
    <nav className="flex items-center gap-2 text-sm mb-6">
      <Link 
        href={`/${paramsString}`}
        className="text-gray-600 hover:text-blue-600 transition"
      >
        Home
      </Link>

      {breadcrumbs.map((crumb, index) => {
        const isLast = index === breadcrumbs.length - 1;
        const hrefWithParams = `${crumb.href}${paramsString}`;

        return (
          <div key={crumb.href} className="flex items-center gap-2">
            <span className="text-gray-400">/</span>
            {isLast ? (
              <span className="text-gray-900 font-semibold">
                {crumb.label}
              </span>
            ) : (
              <Link
                href={hrefWithParams}
                className="text-gray-600 hover:text-blue-600 transition"
              >
                {crumb.label}
              </Link>
            )}
          </div>
        );
      })}

      {/* Show active filters */}
      {currentParams && (
        <span className="ml-2 px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded">
          Filtered
        </span>
      )}
    </nav>
  );
}

// URL: /blog/tech?category=tutorials&sort=recent
// Breadcrumbs: Home / Blog / Tech (Filtered)
// ✅ Combines pathname and searchParams
// ✅ Preserves filters in breadcrumb links
// ✅ Shows filter indicator

Best Practices

1. Wrap useSearchParams in Suspense

TYPESCRIPT
// ✅ GOOD: Wrapped in Suspense
import { Suspense } from 'react';

export default function Page() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <SearchComponent />
    </Suspense>
  );
}

// ❌ BAD: No Suspense (de-opts to client-side rendering)
export default function Page() {
  return <SearchComponent />;
}

2. Use scroll: false for Filter Updates

TYPESCRIPT
// ✅ GOOD: Don't scroll to top on filter change
router.push(`?${params.toString()}`, { scroll: false });

// ❌ BAD: Scrolls to top on every filter
router.push(`?${params.toString()}`);

3. Provide Default Values

TYPESCRIPT
// ✅ GOOD: Default values for missing params
const page = Number(searchParams.get('page')) || 1;
const category = searchParams.get('category') || 'all';
const sort = searchParams.get('sort') || 'recent';

// ❌ BAD: No defaults (null values)
const page = searchParams.get('page');
const category = searchParams.get('category');

4. Use useCallback for Update Functions

TYPESCRIPT
// ✅ GOOD: Memoize update function
const updateFilter = useCallback((key: string, value: string) => {
  const params = new URLSearchParams(searchParams.toString());
  params.set(key, value);
  router.push(`?${params.toString()}`);
}, [searchParams, router]);

// Prevents unnecessary re-renders

5. Clean Up Empty Parameters

TYPESCRIPT
// ✅ GOOD: Remove empty parameters
const updateFilter = (key: string, value: string) => {
  const params = new URLSearchParams(searchParams.toString());
  
  if (!value || value === 'all') {
    params.delete(key); // Remove empty params
  } else {
    params.set(key, value);
  }
  
  router.push(`?${params.toString()}`);
};

// URL: /blog?category=tech (clean)
// Not: /blog?category=tech&sort= (dirty)

Key Takeaways

  • usePathname() - returns current pathname string
  • useSearchParams() - returns URLSearchParams object
  • Client Components only - require 'use client'
  • Wrap in Suspense - useSearchParams needs Suspense
  • Read-only - use useRouter to update params
  • Active links - compare pathname for highlighting
  • URL state - store filters, page, sort in URL
  • Shareable - URLs with params are shareable

What's Next?

You've mastered reading pathname and search parameters! Next, we'll explore Active Links and Navigation States—advanced techniques for styling active links, managing navigation states, showing loading indicators during navigation, and creating sophisticated navigation UI.

You'll learn to build professional navigation components with proper visual feedback, loading states, and user-friendly interactions.

🔗 URL as State

Using URL parameters for filters, pagination, and sort order is a best practice. It makes URLs shareable, enables browser back/forward, and improves SEO. Always consider storing UI state in the URL when possible!

Test Your Understanding

Question 1 of 4

What does usePathname() return?

Master usePathname and useSearchParams hooks in Next.js! Learn to read routes and query parameters.

Previous
useRouter Hook for Programmatic Navigation
Next
Active Links and Navigation States

Master Next.js Navigation

Join 2,000+ developers building dynamic Next.js navigation. Get the next lesson on active links and navigation states - 100% FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

NextJS Tutorials

0 of 70 completed

Your Progress0%

Topics

Getting Started

  • What is Next.js?
  • Next.js vs React - Key Differences
  • Creating Your First Next.js 15 Project
  • Next.js Project Structure Explained
  • App Router vs Pages Router

Routing Fundamentals

  • File-Based Routing Basics
  • Creating Pages with page.tsx
  • Dynamic Routes and Route Parameters
  • Catch-All and Optional Catch-All Routes
  • Route Groups for Organization
  • Parallel Routes
  • Intercepting Routes

Layouts and Pages

  • Understanding Layouts
  • Root Layout and Global Configuration
  • Nested Layouts
  • Templates vs Layouts
  • Loading States with loading.tsx
  • Error Handling with error.tsx

Server and Client Components

  • Understanding Server Components
  • Client Components with 'use client'
  • When to Use Server vs Client Components
  • Component Composition Patterns
  • Passing Props Between Server and Client
  • Server Component Patterns and Best Practices

Data Fetching

  • Fetching Data in Server Components
  • Parallel and Sequential Data Fetching
  • Data Fetching Patterns and Strategies
  • Caching and Revalidation
  • Revalidate and Cache Tags
  • Handling Loading and Error States in Data Fetching

Navigation and Links

  • Link Component Basics
  • useRouter Hook for Programmatic Navigation
  • usePathname and useSearchParams Hooks
  • Active Links and Navigation States
  • Redirects and Navigation Guards

Styling in Next.js

  • CSS Modules in Next.js
  • Tailwind CSS Setup and Configuration
  • Global Styles and CSS Variables
  • Next.js Font Optimization

Images and Media

  • Next.js Image Component Basics
  • Image Optimization and Best Practices
  • Working with Static Assets

Forms and Data Mutations

  • Understanding Server Actions
  • Form Handling with Server Actions
  • Form Validation and Error Handling
  • useFormStatus and useFormState Hooks
  • Revalidating Data After Mutations
  • Optimistic Updates

Metadata and SEO

  • Static Metadata Configuration
  • Dynamic Metadata Generation
  • Open Graph and Social Media Cards
  • Sitemap and Robots.txt

API Routes and Route Handlers

  • Route Handlers Introduction
  • GET and POST Request Handlers
  • Dynamic API Routes
  • Request and Response Objects
  • API Error Handling and Status Codes

Middleware and Advanced Features

  • Introduction to Middleware
  • Authentication with Middleware
  • Environment Variables and Configuration
  • Streaming and Suspense
  • Not Found and Global Error Pages

Deployment and Optimization

  • Understanding Static and Dynamic Rendering
  • generateStaticParams for Static Generation
  • Build and Production Optimization
  • Deploying to Vercel
  • Alternative Deployment Options
  • Performance Monitoring and Analytics

Real-World Projects

  • Project 1: E-commerce Product Catalog
  • Project 2: Dashboard with Authentication
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo