Before we dive deep into Next.js's powerful data fetching capabilities, it's crucial to understand the fundamental concepts of data fetching in web applications in general. At its core, data fetching is the process of retrieving information from a source (like a database, an API, or a static file) and making it available to your users within your web application.
Web applications, especially dynamic ones, rarely exist in isolation. They need to display information that changes, such as user profiles, product listings, news articles, or real-time updates. Data fetching is the mechanism that bridges the gap between your application's frontend and the backend or external data sources.
Think of it like this: your web application is a restaurant, and the data is the food. The kitchen (backend/API) prepares the food, and the waiter (data fetching mechanism) brings it to your table (the user's browser).
The 'where' and 'when' of data fetching significantly impact the user experience and performance of your application. Historically, this has evolved with various approaches, each with its own trade-offs.
Traditionally, the most common approach was Client-Side Rendering (CSR). In CSR, the browser downloads a minimal HTML file and then JavaScript takes over to fetch data and render the entire page. This provides a highly interactive experience after the initial load but can lead to a blank page or loading spinners while data is being fetched.
graph LR
A[Browser] -- 1. Request HTML --> B(Server)
B -- 2. Respond with HTML & JS bundle --> A
A -- 3. Execute JS, Fetch Data --> C(API/Database)
C -- 4. Respond with Data --> A
A -- 5. Render UI --> D[User View]
To combat the initial loading times of CSR, Server-Side Rendering (SSR) emerged. With SSR, the server fetches the data and renders the HTML on the server before sending it to the browser. This means the user sees a fully rendered page almost instantly, improving perceived performance and SEO. However, each page request involves a round trip to the server.
graph LR
A[User] -- 1. Request Page --> B(Server)
B -- 2. Fetch Data --> C(API/Database)
C -- 3. Respond with Data --> B
B -- 4. Render HTML --> B
B -- 5. Respond with HTML & JS bundle --> D[Browser]
D -- 6. Hydrate JS --> D
D -- 7. User Interaction --> D