May 27, 2025
Next.js
Data Fetching Patterns in Next.js — Understanding Utility Functions, API Routes, and Server Actions

Overview
While working on my Next.js portfolio site, I wanted to manage article data as a local JSON file within the project. When thinking about how to access that data from components, I recalled seeing tutorials that used API Routes. However, I also came across examples that used utility functions, and I wasn’t sure which approach to take.
After doing some research, I was able to organize my thoughts more clearly
- Next.js App Router uses Server Components by default
- In Server Components, I can safely use utility functions to directly read from local files or perform server-side logic
- When working with user interaction or external APIs from the client, API Routes are a better choice
- If I need to perform data mutations (e.g. create, update, delete), especially via forms or client-side events, Server Actions are the most appropriate
This helped me build a mental model for choosing the right data fetching strategy depending on the context.
What I Learned
-
Utility Functions
- Run only on the server (inside Server Components)
- Not exposed to the client, so safe for secrets
- Can't be called from client components
-
API Routes
- Define custom endpoints (e.g. /api/posts)
- Can be called from client components via
fetch()
- Good for hiding API keys and credentials when using external APIs
-
Server Actions
- Marked with
'use server'
- Designed for form submissions or client-side events
- Functions feel like direct function calls, but Next.js handles serialization and transmission
- Automatically converted into POST requests under the hood
- Marked with