Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
menu
  1. Home
  2. /Web Development
  3. /Nextjs
  4. /Link Component
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

Link Component Basics

Client-side navigation with the Next.js Link component

Navigation is fundamental to any web application. The Next.js Link component provides client-side navigation that's faster than traditional page loads, with automatic prefetching for instant page transitions. Unlike regular <a> tags that reload the entire page, Link components navigate smoothly while preserving client-side state and avoiding unnecessary re-renders. Let's master the Link component!

Why Use Link Component?

❌ Regular <a> Tag

TYPESCRIPT
// Traditional navigation
<a href="/blog">Blog</a>

// Problems:
// ❌ Full page reload
// ❌ JavaScript re-downloads
// ❌ Client state lost
// ❌ Slow navigation
// ❌ No prefetching

✅ Next.js Link Component

TYPESCRIPT
import Link from 'next/link';

// Client-side navigation
<Link href="/blog">Blog</Link>

// Benefits:
// ✅ No page reload
// ✅ Instant navigation
// ✅ Preserves state
// ✅ Automatic prefetching
// ✅ Faster experience

Performance Impact

  • Regular <a>: 1-2 seconds full page load
  • Link component: ~50ms instant navigation (with prefetch)
  • Improvement: 20-40x faster navigation!

Basic Link Usage

Simple Link

app/components/Navbar.tsx
import Link from 'next/link';

export function Navbar() {
  return (
    <nav className="flex gap-6 p-4 bg-gray-100">
      <Link href="/">Home</Link>
      <Link href="/about">About</Link>
      <Link href="/blog">Blog</Link>
      <Link href="/contact">Contact</Link>
    </nav>
  );
}

// ✅ Import Link from 'next/link'
// ✅ Use href prop for the destination
// ✅ Link renders as <a> tag in HTML
// ✅ Navigation is client-side (no page reload)

Link with Styling

TYPESCRIPT
import Link from 'next/link';

export function Navbar() {
  return (
    <nav className="flex gap-6 p-4 bg-gray-100">
      <Link 
        href="/"
        className="text-blue-600 hover:text-blue-800 font-semibold transition"
      >
        Home
      </Link>
      
      <Link 
        href="/blog"
        className="text-blue-600 hover:text-blue-800 font-semibold transition"
      >
        Blog
      </Link>
    </nav>
  );
}

// ✅ Add className directly to Link
// ✅ All standard HTML attributes work
// ✅ Hover effects, transitions, etc.

Link with Children

TYPESCRIPT
import Link from 'next/link';

export function BlogCard({ post }: { post: Post }) {
  return (
    <Link href={/blog/${post.slug}}>
      <article className="border rounded-lg p-6 hover:shadow-lg transition cursor-pointer">
        <h2 className="text-2xl font-bold mb-2">{post.title}</h2>
        <p className="text-gray-600 mb-4">{post.excerpt}</p>
        <span className="text-blue-600 font-semibold">Read more →</span>
      </article>
    </Link>
  );
}

// ✅ Entire card is clickable
// ✅ Wraps complex children
// ✅ Semantic and accessible

Dynamic Links

Template Literals

app/blog/page.tsx
import Link from 'next/link';

interface Post {
  id: string;
  slug: string;
  title: string;
  excerpt: string;
}

async function BlogPage() {
  const posts: Post[] = await fetch('https://api.example.com/posts')
    .then(r => r.json());

  return (
    <div className="container mx-auto px-4 py-8">
      <h1 className="text-3xl font-bold mb-8">Blog Posts</h1>
      
      <div className="space-y-6">
        {posts.map(post => (
          <article key={post.id} className="border rounded-lg p-6">
            <Link href={/blog/${post.slug}}>
              <h2 className="text-2xl font-semibold mb-2 hover:text-blue-600 transition">
                {post.title}
              </h2>
            </Link>
            <p className="text-gray-700 mb-4">{post.excerpt}</p>
            <Link 
              href={/blog/${post.slug}}
              className="text-blue-600 hover:underline"
            >
              Read more →
            </Link>
          </article>
        ))}
      </div>
    </div>
  );
}

export default BlogPage;

// ✅ Dynamic href with template literals
// ✅ Each post links to its unique page
// ✅ Type-safe with TypeScript

Object-Style href

TYPESCRIPT
import Link from 'next/link';

// Link with query parameters
<Link 
  href={{
    pathname: '/blog',
    query: { category: 'tech', page: '1' },
  }}
>
  Tech Blog
</Link>
// Navigates to: /blog?category=tech&page=1

// Link with hash
<Link 
  href={{
    pathname: '/docs',
    hash: 'installation',
  }}
>
  Installation
</Link>
// Navigates to: /docs#installation

// Complex example
<Link 
  href={{
    pathname: '/search',
    query: { 
      q: 'next.js',
      category: 'tutorials',
      sort: 'recent' 
    },
  }}
>
  Search Tutorials
</Link>
// Navigates to: /search?q=next.js&category=tutorials&sort=recent

// ✅ Object format for complex URLs
// ✅ Query parameters automatically encoded
// ✅ Type-safe pathname

Prefetching

Next.js automatically prefetches linked pages when Links enter the viewport:

How Prefetching Works

  1. Link enters viewport - Next.js detects the Link
  2. Background fetch - Page data is fetched in the background
  3. Data cached - Fetched data is stored in Router Cache
  4. User clicks - Navigation is instant (data already loaded)

Default Prefetching Behavior

TYPESCRIPT
import Link from 'next/link';

// Prefetching ON by default (production only)
<Link href="/blog">Blog</Link>

// Explicitly enable prefetching
<Link href="/blog" prefetch={true}>
  Blog
</Link>

// Disable prefetching
<Link href="/admin" prefetch={false}>
  Admin Dashboard
</Link>

// ✅ Prefetch=true (default): Prefetches automatically
// ✅ Prefetch=false: Only fetches on click
// ⚠️  Prefetching only happens in production, not development

When to Disable Prefetching

TYPESCRIPT
// Disable prefetching for:

// 1. Authenticated/protected routes
<Link href="/dashboard" prefetch={false}>
  Dashboard
</Link>

// 2. Less likely to be clicked
<Link href="/privacy-policy" prefetch={false}>
  Privacy Policy
</Link>

// 3. External or dynamic content
<Link href="/api/download" prefetch={false}>
  Download Report
</Link>

// 4. Large pages (to save bandwidth)
<Link href="/massive-gallery" prefetch={false}>
  Full Gallery
</Link>

// ✅ Saves bandwidth
// ✅ Reduces unnecessary requests
// ✅ Better for authenticated routes

⚠️ Prefetching in Development

Prefetching is disabled in development mode to avoid too many requests during development. Test prefetching behavior in production builds.

Special Link Cases

External Links

TYPESCRIPT
// ❌ BAD: Using Link for external URLs
import Link from 'next/link';

<Link href="https://google.com">Google</Link>
// Works, but unnecessary - Link is for internal navigation

// ✅ GOOD: Use regular <a> for external links
<a 
  href="https://google.com"
  target="_blank"
  rel="noopener noreferrer"
  className="text-blue-600 hover:underline"
>
  Google
</a>

// ✅ External links should:
// - Use <a> tag
// - Have target="_blank" to open in new tab
// - Have rel="noopener noreferrer" for security
// - Not use Link component

Replace vs Push

TYPESCRIPT
import Link from 'next/link';

// Default: Push to history (can go back)
<Link href="/new-page">Go to New Page</Link>

// Replace: Replace current history entry (can't go back)
<Link href="/new-page" replace>
  Go to New Page
</Link>

// Use cases for replace:
// ✅ Login redirects: <Link href="/dashboard" replace>
// ✅ Step-by-step flows where you don't want back button
// ✅ Replacing temporary/intermediate pages

// Example: After login, replace login page with dashboard
<Link href="/dashboard" replace>
  Continue to Dashboard
</Link>
// User can't click back to login page

Scroll Behavior

TYPESCRIPT
import Link from 'next/link';

// Default: Scroll to top on navigation
<Link href="/about">About</Link>

// Preserve scroll position
<Link href="/about" scroll={false}>
  About
</Link>

// Use cases for scroll={false}:
// ✅ Pagination: Keep scroll position when loading more
// ✅ Filter changes: Don't scroll to top on filter
// ✅ Tab switching: Stay at current scroll

// Example: Pagination
<Link 
  href={/blog?page=${currentPage + 1}}
  scroll={false}
>
  Next Page
</Link>
// User stays at same scroll position

Shallow Routing (Query Parameter Updates)

TYPESCRIPT
import Link from 'next/link';

// Shallow: Update URL without re-running data fetching
<Link 
  href="/blog?sort=recent"
  shallow={true}
>
  Sort by Recent
</Link>

// When to use shallow:
// ✅ Updating filters without refetching data
// ✅ Changing sort order
// ✅ Updating tabs/views without data change

// Example: Filter buttons
<div className="flex gap-2">
  <Link href="/blog?category=tech" shallow>
    Tech
  </Link>
  <Link href="/blog?category=design" shallow>
    Design
  </Link>
</div>
// Updates URL without re-fetching page data

Practical Examples

Navigation Menu

components/Navbar.tsx
import Link from 'next/link';

export function Navbar() {
  return (
    <nav className="bg-white shadow-md">
      <div className="container mx-auto px-4 py-4">
        <div className="flex items-center justify-between">
          {/* Logo */}
          <Link href="/" className="text-2xl font-bold text-blue-600">
            MyApp
          </Link>

          {/* Navigation Links */}
          <ul className="flex gap-6">
            <li>
              <Link 
                href="/"
                className="text-gray-700 hover:text-blue-600 transition font-medium"
              >
                Home
              </Link>
            </li>
            <li>
              <Link 
                href="/about"
                className="text-gray-700 hover:text-blue-600 transition font-medium"
              >
                About
              </Link>
            </li>
            <li>
              <Link 
                href="/blog"
                className="text-gray-700 hover:text-blue-600 transition font-medium"
              >
                Blog
              </Link>
            </li>
            <li>
              <Link 
                href="/contact"
                className="text-gray-700 hover:text-blue-600 transition font-medium"
              >
                Contact
              </Link>
            </li>
          </ul>

          {/* CTA Button */}
          <Link 
            href="/signup"
            className="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition font-semibold"
          >
            Sign Up
          </Link>
        </div>
      </div>
    </nav>
  );
}

// ✅ Professional navigation bar
// ✅ All links use Link component
// ✅ Styled with Tailwind
// ✅ Hover effects and transitions

Blog Card with Link

components/BlogCard.tsx
import Link from 'next/link';
import Image from 'next/image';

interface Post {
  slug: string;
  title: string;
  excerpt: string;
  image: string;
  author: {
    name: string;
    avatar: string;
  };
  publishedAt: string;
}

export function BlogCard({ post }: { post: Post }) {
  return (
    <article className="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-xl transition">
      {/* Image Link */}
      <Link href={/blog/${post.slug}}>
        <div className="relative h-48 w-full">
          <Image
            src={post.image}
            alt={post.title}
            fill
            className="object-cover"
          />
        </div>
      </Link>

      <div className="p-6">
        {/* Title Link */}
        <Link href={/blog/${post.slug}}>
          <h2 className="text-2xl font-bold mb-3 hover:text-blue-600 transition">
            {post.title}
          </h2>
        </Link>

        {/* Excerpt */}
        <p className="text-gray-600 mb-4 line-clamp-3">
          {post.excerpt}
        </p>

        {/* Author Info */}
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <Image
              src={post.author.avatar}
              alt={post.author.name}
              width={40}
              height={40}
              className="rounded-full"
            />
            <div>
              <p className="font-semibold text-sm">{post.author.name}</p>
              <p className="text-xs text-gray-500">{post.publishedAt}</p>
            </div>
          </div>

          {/* Read More Link */}
          <Link 
            href={/blog/${post.slug}}
            className="text-blue-600 hover:underline font-semibold"
          >
            Read more →
          </Link>
        </div>
      </div>
    </article>
  );
}

// ✅ Multiple clickable areas (image, title, button)
// ✅ All use same Link destination
// ✅ Professional card design
// ✅ Hover effects on interactive elements

Breadcrumb Navigation

components/Breadcrumbs.tsx
import Link from 'next/link';

interface Breadcrumb {
  label: string;
  href: string;
}

export function Breadcrumbs({ items }: { items: Breadcrumb[] }) {
  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>

      {items.map((item, index) => {
        const isLast = index === items.length - 1;

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

// Usage:
// <Breadcrumbs
//   items={[
//     { label: 'Blog', href: '/blog' },
//     { label: 'Tech', href: '/blog/tech' },
//     { label: 'My Post', href: '/blog/tech/my-post' },
//   ]}
// />

// ✅ Clear navigation hierarchy
// ✅ Current page not linked
// ✅ All previous levels linked

Link Component Examples

Project structure with Link component usage

appImportant

Select a file or folder to see details

Link Component Best Practices

1. Always Use Link for Internal Navigation

TYPESCRIPT
// ✅ GOOD: Use Link for internal routes
import Link from 'next/link';

<Link href="/about">About</Link>
<Link href="/blog/my-post">My Post</Link>

// ❌ BAD: Using <a> for internal routes
<a href="/about">About</a>
// Causes full page reload, slower navigation

2. Use <a> for External Links

TYPESCRIPT
// ✅ GOOD: Use <a> for external links
<a 
  href="https://github.com/yourrepo"
  target="_blank"
  rel="noopener noreferrer"
>
  GitHub
</a>

// ❌ BAD: Using Link for external URLs
<Link href="https://github.com/yourrepo">GitHub</Link>

3. Disable Prefetch for Authenticated Routes

TYPESCRIPT
// ✅ GOOD: Disable prefetch for protected routes
<Link href="/dashboard" prefetch={false}>
  Dashboard
</Link>

<Link href="/admin" prefetch={false}>
  Admin
</Link>

// Prevents prefetching protected content before login

4. Make Large Click Areas

TYPESCRIPT
// ✅ GOOD: Entire card is clickable
<Link href="/blog/post-1">
  <article className="p-6 border rounded hover:shadow-lg">
    <h2>{post.title}</h2>
    <p>{post.excerpt}</p>
  </article>
</Link>

// ❌ BAD: Only text is clickable
<article className="p-6 border rounded">
  <Link href="/blog/post-1">
    <h2>{post.title}</h2>
  </Link>
  <p>{post.excerpt}</p>
</article>

5. Provide Visual Feedback

TYPESCRIPT
// ✅ GOOD: Hover effects and transitions
<Link 
  href="/about"
  className="text-blue-600 hover:text-blue-800 hover:underline transition-colors"
>
  About
</Link>

// ✅ GOOD: Interactive states
<Link 
  href="/blog"
  className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 active:scale-95 transition"
>
  Blog
</Link>

// Users know it's clickable

Key Takeaways

  • Import from 'next/link' - always use Link component
  • Client-side navigation - no page reload, instant
  • Automatic prefetching - pages load in background
  • href prop - string or object for destination
  • Use <a> for external - Link for internal only
  • Disable prefetch - for authenticated or unlikely routes
  • Style with className - works like regular HTML
  • 20-40x faster - compared to full page loads

What's Next?

You've mastered the Link component! Next, we'll explore the useRouter Hook for Programmatic Navigation—how to navigate programmatically in response to events like form submissions, button clicks, or API responses. You'll learn to control navigation with code!

The useRouter hook gives you full control over navigation, allowing you to navigate after user actions, with custom logic, or based on application state.

⚡ Prefetching Magic

The automatic prefetching in Link components is one of Next.js's superpowers. Pages load instantly because they're already fetched before the user clicks. This makes your app feel incredibly fast with zero extra code!

Test Your Understanding

Question 1 of 4

What is the main benefit of using Next.js Link component?

Master the Next.js Link component for fast client-side navigation with automatic prefetching!

Previous
Handling Loading and Error States in Data Fetching
Next
useRouter Hook for Programmatic Navigation

Master Next.js Navigation

Join 2,000+ developers building fast Next.js apps. Get the next lesson on programmatic navigation with useRouter - 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