Mastering Next.js API Features: Search, Pagination, Filters, Sorting, and Limits Made Easy
APIs are the backbone of modern web applications, enabling dynamic and interactive experiences. In this guide, we’ll walk through building a feature-rich API in Next.js that includes search, pagination, filtering, sorting, and limit options, making it perfect for scenarios like building product lists, user directories, or any large datasets. 🛠️

🧩 Why Choose Next.js for API Management?
Next.js provides a robust framework for creating server-side APIs. Its api folder in the /pages directory makes defining routes intuitive. Moreover, with built-in features like server-side rendering (SSR) and static generation, you can optimize API performance seamlessly.
🗂️ Folder Structure for API Management
Here’s an ideal folder structure for our project:
my-nextjs-project/
├── pages/
│ ├── api/
│ │ └── items/
│ │ └── index.js # API route for handling items
├── components/
│ └── SearchBar.js # Frontend search component
├── utils/
│ └── apiHelpers.js # Helper functions for API operations
├── data/
│ └── items.json # Mock data for demonstration
├── styles/
│ └── globals.css
├── public/
├── package.json
└── next.config.js🚀 Step-by-Step Guide
1. Setting Up the API
pages/api/items/index.js
This API route will handle search, pagination, filters, sorting, and limits.
import items from '../../../data/items.json';
export default function handler(req, res) {
const { search, page = 1, limit = 10, sort, filter } = req.query;
let filteredItems = items;
// 🔍 Search
if (search) {
filteredItems = filteredItems.filter(item =>
item.name.toLowerCase().includes(search.toLowerCase())
);
}
// 🏷️ Filter
if (filter) {
const filters = filter.split(',');
filteredItems = filteredItems.filter(item =>
filters.includes(item.category)
);
}
// 🔃 Sort
if (sort) {
const [key, order] = sort.split(':'); // Example: sort=name:asc
filteredItems.sort((a, b) => {
if (order === 'asc') return a[key].localeCompare(b[key]);
if (order === 'desc') return b[key].localeCompare(a[key]);
return 0;
});
}
// 📑 Pagination
const startIndex = (page - 1) * limit;
const paginatedItems = filteredItems.slice(startIndex, startIndex + Number(limit));
res.status(200).json({
data: paginatedItems,
total: filteredItems.length,
page: Number(page),
limit: Number(limit),
});
}2. Mock Data for Testing
data/items.json
Create a sample dataset for testing.
[
{ "id": 1, "name": "Item A", "category": "electronics" },
{ "id": 2, "name": "Item B", "category": "fashion" },
{ "id": 3, "name": "Item C", "category": "electronics" },
{ "id": 4, "name": "Item D", "category": "books" }
// Add more items as needed
]3. Frontend Implementation
components/SearchBar.js
Create a simple search bar component for user input.
import { useState } from 'react';
export default function SearchBar({ onSearch }) {
const [query, setQuery] = useState('');
const handleSearch = () => {
onSearch(query);
};
return (
<div>
<input
type="text"
placeholder="Search items..."
value={query}
onChange={e => setQuery(e.target.value)}
/>
<button onClick={handleSearch}>Search</button>
</div>
);
}4. Fetch and Display Data
Example Page: pages/index.js
import { useState, useEffect } from 'react';
import SearchBar from '../components/SearchBar';
export default function Home() {
const [items, setItems] = useState([]);
const [queryParams, setQueryParams] = useState({ search: '', page: 1 });
useEffect(() => {
const fetchData = async () => {
const queryString = new URLSearchParams(queryParams).toString();
const response = await fetch(`/api/items?${queryString}`);
const data = await response.json();
setItems(data.data);
};
fetchData();
}, [queryParams]);
const handleSearch = search => {
setQueryParams(prev => ({ ...prev, search, page: 1 }));
};
return (
<div>
<h1>Items List</h1>
<SearchBar onSearch={handleSearch} />
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}5. Styling the App
styles/globals.css
body {
font-family: Arial, sans-serif;
margin: 20px;
padding: 0;
}
input {
margin-right: 10px;
}🛠️ Features Breakdown
- Search: Query results using keywords.
- Pagination: Navigate through large datasets by limiting items per page.
- Filter: Narrow results by specific criteria like categories.
- Sort: Arrange items in ascending or descending order.
- Limit: Control the number of items returned per request.
📝 Conclusion
Building robust APIs in Next.js with features like search, pagination, filtering, and sorting is essential for modern web applications. This setup can scale with your application, ensuring a seamless user experience.





