Skip to content

paginate

Parses pagination query parameters into structured shapes on the domain accumulator (acc). Works in concert with send()’s paginate: true option to automatically generate RFC 8288 Link headers and X-Total-Count for paginated responses.

Supports two strategies: offset (page/per_page) and cursor (opaque cursor token + limit).

Pipeline stage: Negotiation

import {paginate} from '@centralping/ergo';
Option Type Default Description
strategy 'offset' | 'cursor' 'offset' Pagination strategy
defaultPage number 1 Default page number (offset strategy)
defaultPerPage number 20 Default items per page (offset strategy)
maxPerPage number 100 Maximum items per page (offset strategy)
defaultLimit number 20 Default item limit (cursor strategy)
maxLimit number 100 Maximum item limit (cursor strategy)

Returns parsed pagination parameters stored at acc.paginate. The shape depends on the active strategy:

Offset strategy:

{
strategy: 'offset',
page: 1, // clamped to ≥ 1
perPage: 20, // clamped to ≤ maxPerPage
offset: 0, // computed: (page - 1) * perPage
limit: 20, // same as perPage
}

Cursor strategy:

{
strategy: 'cursor',
cursor: undefined, // opaque string from query, or undefined on first page
limit: 20, // clamped to ≤ maxLimit
}

None. Invalid or missing query parameters fall back to defaults silently.

import http from 'node:http';
import {compose, url, paginate, handler} from '@centralping/ergo';
const pipeline = compose(
url(),
paginate(),
async (req, res, acc) => {
const {offset, limit} = acc.paginate;
const items = await db.find(offset, limit);
const total = await db.count();
return {
response: {body: items, paginate: {total}},
};
},
);
const server = http.createServer(
handler(pipeline, {paginate: true}),
);

When using standalone compose(), you must include url() before paginate() — the pagination middleware reads parsed query parameters from acc.url.query.

  • Pagination — End-to-end offset and cursor pagination with auto-generated Link headers

See the auto-generated paginate API docs.