Technology

Building Infinite Scroll with Next.js and TMDB API

Learn how to implement smooth infinite scroll functionality in React applications. This comprehensive tutorial covers state management, API integration, performance optimization, and responsive design patterns using The Movie Database API.

10 min read
Published

Complete Tutorial Code

Follow along with the complete source code for this infinite scroll tutorial. Includes a full Next.js implementation with TMDB API integration and responsive design.

View on GitHub

Introduction

Infinite scroll has become a cornerstone of modern web applications, providing users with seamless content discovery experiences. From social media feeds to e-commerce product listings, this pattern eliminates the need for traditional pagination while keeping users engaged with continuous content loading.

This tutorial demonstrates how to build a robust infinite scroll implementation using Next.js 16, TypeScript, and The Movie Database (TMDB) API. We'll cover everything from basic scroll detection to advanced performance optimizations, ensuring your application delivers a smooth user experience across all devices.

What is Infinite Scroll?

Infinite scroll is a user interface pattern that automatically loads additional content as users approach the end of the current page. This technique creates a continuous browsing experience without requiring users to click through pagination controls.

Traditional Pagination

Page 1 → Click Next → Page 2
Manual navigation required

Users must actively navigate between pages

Infinite Scroll

Scroll down → Auto-load → More content appears → Seamless experience

Content loads automatically as users scroll

Key Features

Our infinite scroll implementation includes several essential features that ensure optimal performance and user experience:

Automatic Loading

Detects when users approach the bottom and automatically fetches more content without user intervention.

Responsive Design

Mobile-first responsive grid that adapts from 1 column on mobile to 4 columns on desktop screens.

Performance Optimized

Debounced scroll events and efficient state management prevent excessive API calls and ensure smooth scrolling.

Error Handling

Graceful error handling with user-friendly messages and loading states for better user experience.

Tech Stack

This tutorial uses modern web development technologies to create a production-ready infinite scroll implementation:

Next.js 16: React framework with App Router for modern web applications
TypeScript: Type safety and enhanced developer experience
Tailwind CSS: Utility-first styling and responsive design
TMDB API: The Movie Database API for rich movie data
Axios & Lodash: HTTP client and utility functions for optimization

Project Structure

The application follows a clean, organized structure that separates concerns and promotes maintainability:

src/app/
├── page.tsx                    # Main page with infinite scroll logic
├── layout.tsx                  # Root layout
├── globals.css                 # Global styles
└── components/
    ├── MovieCard.tsx           # Individual movie card component
    └── MovieCardSkeleton.tsx   # Loading skeleton component

Core Implementation

State Management

The infinite scroll functionality relies on React hooks to manage application state efficiently. Here's how we structure our state:

const [page, setPage] = useState(1);           // Current page number
const [data, setData] = useState([]);           // Array of movie data
const [loading, setLoading] = useState(false);  // Loading state
const [error, setError] = useState(null);       // Error handling

Scroll Detection

The heart of infinite scroll is detecting when users approach the bottom of the page. Our implementation triggers loading when users are within 300 pixels of the bottom:

const handleScroll = () => {
  if (
    document.body.scrollHeight - 300 <
    window.scrollY + window.innerHeight
  ) {
    setPage((prevPage) => prevPage + 1);
  }
};

Performance Optimization

To prevent excessive API calls and ensure smooth scrolling, we implement debouncing using Lodash. This limits how frequently the scroll handler can execute:

import { debounce } from 'lodash';

const debouncedHandleScroll = debounce(handleScroll, 500);

useEffect(() => {
  window.addEventListener('scroll', debouncedHandleScroll);
  return () => window.removeEventListener('scroll', debouncedHandleScroll);
}, []);

API Integration

We use The Movie Database (TMDB) API to fetch popular movies with pagination support. The API integration includes proper authentication and error handling:

const fetchMovies = async () => {
  try {
    setLoading(true);
    const response = await axios.get(
      `https://api.themoviedb.org/3/movie/popular?language=en-US&page=${page}`,
      {
        headers: {
          Authorization: `Bearer ${process.env.NEXT_PUBLIC_TMDB_READ_ACCESS_TOKEN}`
        }
      }
    );
    setData(prevData => [...prevData, ...response.data.results]);
  } catch (err) {
    setError('Failed to load movies');
  } finally {
    setLoading(false);
  }
};

Component Architecture

MovieCard Component

The MovieCard component displays individual movie information with poster images, titles, descriptions, and ratings. It uses responsive design principles to adapt to different screen sizes:

interface Movie {
  id: number;
  title: string;
  overview: string;
  poster_path: string;
  vote_average: number;
}

const MovieCard: React.FC<{ movie: Movie }> = ({ movie }) => {
  return (
    <div className="bg-gray-800 rounded-lg overflow-hidden shadow-lg hover:shadow-xl transition-shadow">
      <img 
        src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
        alt={movie.title}
        className="w-full h-64 object-cover"
      />
      <div className="p-4">
        <h3 className="text-lg font-semibold mb-2">{movie.title}</h3>
        <p className="text-gray-400 text-sm mb-2 line-clamp-3">
          {movie.overview}
        </p>
        <div className="flex items-center">
          <span className="text-yellow-400">★</span>
          <span className="ml-1 text-sm">{movie.vote_average.toFixed(1)}</span>
        </div>
      </div>
    </div>
  );
};

Loading Skeleton

The MovieCardSkeleton component provides visual feedback during loading states, maintaining layout stability and improving perceived performance:

const MovieCardSkeleton: React.FC = () => {
  return (
    <div className="bg-gray-800 rounded-lg overflow-hidden shadow-lg animate-pulse">
      <div className="w-full h-64 bg-gray-700"></div>
      <div className="p-4">
        <div className="h-6 bg-gray-700 rounded mb-2"></div>
        <div className="h-4 bg-gray-700 rounded mb-1"></div>
        <div className="h-4 bg-gray-700 rounded mb-1"></div>
        <div className="h-4 bg-gray-700 rounded w-3/4"></div>
      </div>
    </div>
  );
};

Setup and Configuration

Getting started with the infinite scroll tutorial is straightforward. Follow these steps to set up your development environment:

  1. 1
    Clone the repository:
    git clone https://github.com/audoir/infinite-scroll-tutorial.git
  2. 2
    Install dependencies:
    npm install
  3. 3
    Environment setup:

    Create a .env.local file and add your TMDB API key:

    NEXT_PUBLIC_TMDB_READ_ACCESS_TOKEN=your_token_here

    Get your API key from The Movie Database

  4. 4
    Start the development server:
    npm run dev

    Open http://localhost:3000 in your browser

Best Practices and Considerations

Performance Optimization

Implementing infinite scroll requires careful attention to performance. Here are key strategies we employ:

  • Debouncing: Limit scroll event frequency to prevent excessive API calls
  • Loading States: Provide visual feedback during data fetching
  • Error Boundaries: Graceful error handling for network failures
  • Memory Management: Consider implementing virtualization for large datasets

User Experience

A well-implemented infinite scroll should feel natural and responsive:

  • Smooth Transitions: Use CSS transitions for loading states
  • Skeleton Loading: Maintain layout stability during loading
  • Responsive Design: Adapt to different screen sizes and orientations
  • Accessibility: Ensure keyboard navigation and screen reader support

SEO Considerations

Infinite scroll can impact SEO if not implemented carefully. Consider these strategies:

  • Server-Side Rendering: Ensure initial content is rendered on the server
  • URL Updates: Update URLs to reflect current page state
  • Sitemap Generation: Include paginated URLs in your sitemap
  • Fallback Pagination: Provide traditional pagination as a fallback

Learning Outcomes

By completing this tutorial, you will have gained hands-on experience with:

  • • React hooks for state management and side effects
  • • Event handling and cleanup in React applications
  • • API integration with proper error handling
  • • Performance optimization techniques (debouncing)
  • • Responsive design patterns with Tailwind CSS
  • • TypeScript integration in React applications
  • • Component composition and reusability
  • • Modern Next.js development patterns

Conclusion

Infinite scroll is a powerful pattern that can significantly enhance user engagement when implemented correctly. By combining React hooks, performance optimization techniques, and responsive design principles, we've created a robust solution that works seamlessly across devices.

The techniques demonstrated in this tutorial form the foundation for building scalable, user-friendly infinite scroll implementations. From social media feeds to product catalogs, these patterns can be adapted to various use cases and requirements.

About the Author

Wayne Cheng is the founder and AI app developer at Audoir, LLC. Prior to founding Audoir, he worked as a hardware design engineer for Silicon Valley startups and an audio engineer for creative organizations. He holds an MSEE from UC Davis and a Music Technology degree from Foothill College.

Further Exploration

To continue exploring infinite scroll implementations, check out the complete tutorial repository and experiment with different optimization techniques. Consider adding features like search functionality, filtering, or virtual scrolling for large datasets.

For more web development tutorials and AI-powered tools, visit Audoir .