Data & Auth
Mock API
How the route handlers and mock data layer work, and how to replace them with a real backend.
How Route Handlers Work
Haze Dashboard uses Next.js Route Handlers to serve mock API routes. Files named route.ts in the src/app/api/ directory automatically become API endpoints. Each exported HTTP method (GET, POST, etc.) handles that method:
| File | URL |
|---|---|
| app/api/orders/route.ts | /api/orders |
| app/api/orders/[id]/route.ts | /api/orders/123 |
| app/api/dashboard/overview/route.ts | /api/dashboard/overview |
Pagination Utility
All list endpoints use a shared paginate() helper from src/server/utils/pagination.ts. It accepts query parameters for pagination, search, filtering, and sorting:
| Parameter | Type | Default | Description |
|---|---|---|---|
| page | number | 1 | Current page number |
| per_page | number | 10 | Items per page (max 100) |
| search | string | — | Search term, supports nested paths like customer.name |
| status | string | — | Filter by status field |
| sort | string | — | Field name to sort by |
| order | string | desc | Sort direction: asc or desc |
Response Format
All paginated endpoints return a consistent response structure:
{
"data": [
{ "id": 1, "orderNumber": "ORD-001", "status": "active", "total": 245.00 },
{ "id": 2, "orderNumber": "ORD-002", "status": "pending", "total": 189.50 }
],
"meta": {
"total": 248,
"page": 1,
"perPage": 10,
"lastPage": 25
}
}The meta object provides everything needed to render pagination controls.
Anatomy of a Route Handler
Here is a typical list endpoint. It imports JSON data and passes it through the pagination utility:
// src/app/api/orders/route.ts
import { NextRequest } from 'next/server'
import orders from '@/server/data/orders.json'
import { paginate } from '@/server/utils/pagination'
export async function GET(request: NextRequest) {
return paginate(request, orders, ['orderNumber', 'customer.name', 'customer.email'])
}The third argument to paginate() specifies which fields to search when the search parameter is provided. Nested fields like customer.name are supported via dot notation.
Mock Datasets
All mock data lives in src/server/data/ as JSON files:
| File | Used By |
|---|---|
| orders.json | /orders, /api/orders |
| products.json | /products, /api/products |
| customers.json | /customers, /api/customers |
| invoices.json | /invoices, /api/invoices |
| dashboard-*.json | 5 dashboard variants |
| chat-messages.json, mail.json, kanban.json… | Chat, Mail, Kanban, Calendar, Files |
Adding a New Resource
To add a new API resource (e.g., tasks), follow these steps.
1. Create the data file:
// src/server/data/tasks.json
[
{ "id": 1, "title": "Review pull request", "status": "pending", "priority": "high" },
{ "id": 2, "title": "Update documentation", "status": "in_progress", "priority": "medium" },
{ "id": 3, "title": "Fix navigation bug", "status": "completed", "priority": "high" }
]2. Create the route handler:
// src/app/api/tasks/route.ts
import { NextRequest } from 'next/server'
import tasks from '@/server/data/tasks.json'
import { paginate } from '@/server/utils/pagination'
export async function GET(request: NextRequest) {
return paginate(request, tasks, ['title'])
}The endpoint is immediately available at /api/tasks with full pagination, search, and filter support.
Replacing with a Real API
When you connect a real backend (Laravel, Django, Express, etc.), you have two options:
- Option A: Proxy through the route handlers — Update the handlers in
src/app/api/tofetch()from your real backend. - Option B: Point fetch calls directly — Change the
fetch('/api/orders')calls in page components to point to your external API URL. Delete the route handlers you no longer need.
The key requirement is that your real API returns the same { data: [], meta: {} } response format, or you update the page components to handle the new shape.
Tip
The mock API routes work in production too — Next.js deploys them as serverless functions on Vercel, Netlify, and Cloudflare. Your demo stays fully functional when deployed.
Next Steps
Learn about mock authentication in the Authentication guide, or see how to add new pages that consume these API routes.