{"id":14957513,"url":"https://github.com/expressjs/express-paginate","last_synced_at":"2025-05-16T12:12:00.973Z","repository":{"id":65978531,"uuid":"20779309","full_name":"expressjs/express-paginate","owner":"expressjs","description":"Paginate middleware","archived":true,"fork":false,"pushed_at":"2025-05-14T13:43:12.000Z","size":93,"stargazers_count":425,"open_issues_count":0,"forks_count":83,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-05-14T14:56:53.721Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/expressjs.png","metadata":{"files":{"readme":"Readme.md","changelog":"History.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-06-12T18:58:35.000Z","updated_at":"2025-05-14T13:52:31.000Z","dependencies_parsed_at":"2023-02-19T19:01:16.895Z","dependency_job_id":null,"html_url":"https://github.com/expressjs/express-paginate","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expressjs%2Fexpress-paginate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expressjs%2Fexpress-paginate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expressjs%2Fexpress-paginate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expressjs%2Fexpress-paginate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/expressjs","download_url":"https://codeload.github.com/expressjs/express-paginate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254527099,"owners_count":22085919,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T13:15:01.310Z","updated_at":"2025-05-16T12:12:00.967Z","avatar_url":"https://github.com/expressjs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e [!CAUTION]\n\u003e **This repository is archived and no longer actively maintained.**\n\u003e\n\u003e We are no longer accepting issues, feature requests, or pull requests.\n\u003e For additional support or questions, please visit the [Express.js Discussions page](https://github.com/expressjs/express/discussions).\n\n\n# express-paginate\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n[![MIT License][license-image]][license-url]\n[![Slack][slack-image]][slack-url]\n\n\u003e Node.js pagination middleware and view helpers.\n\n**Looking for a Koa version?**  Try using \u003chttps://github.com/koajs/ctx-paginate\u003e, which is forked directly from this package!\n\n**v0.2.0+**: As of `v0.2.0`, we now allow you to pass `?limit=0` to get infinite (all) results.  This may impose security or performance issues for your application, so we suggest you to write a quick middleware fix such as the one below, or use rate limiting middleware to prevent abuse.\n\n```js\napp.all(function(req, res, next) {\n  // set default or minimum is 10 (as it was prior to v0.2.0)\n  if (req.query.limit \u003c= 10) req.query.limit = 10;\n  next();\n});\n```\n\n\n## Install\n\n```bash\nnpm install -S express-paginate\n```\n\n\n## API\n\n```js\nconst paginate = require('express-paginate');\n```\n\n### paginate\n\nThis creates a new instance of `express-paginate`.\n\n\n### paginate.middleware(limit, maxLimit)\n\nThis middleware validates and supplies default values to `req.skip` (an alias of `req.offset`, which can be used to skip or offset a number of records for pagination, e.g. with Mongoose you would do `Model.find().skip(req.skip)`), `req.query.limit`, `req.query.page`, `res.locals.paginate`, `res.locals.hasPreviousPages`, and `res.locals.hasNextPages`.\n\n#### Arguments\n\n* `limit` a Number to limit results returned per page (defaults to `10`)\n* `maxLimit` a Number to restrict the number of results returned to per page (defaults to `50`) \u0026ndash; through this, users will not be able to override this limit (e.g. they can't pass `?limit=10000` and crash your server)\n\n\n### paginate.href(req)\n\nWhen you use the `paginate` middleware, it injects a view helper function called `paginate.href` as `res.locals.paginate`, which you can use in your views for paginated hyperlinks (e.g. as the `href` in `\u003ca\u003ePrev\u003c/a\u003e` or `\u003ca\u003eNext\u003c/a\u003e`).\n\nBy default, the view helper `paginate.href` is already executed with the inherited `req` variable, therefore it becomes a function capable of returning a String when executed.\n\nWhen executed with `req`, it will return a function with two optional arguments, `prev` (Boolean) and `params` (String).\n\nThe argument `prev` is a Boolean and is completely optional (defaults to `false`).\n\nThe argument `params` is an Object and is completely optional.\n\nPass `true` as the value for `prev` when you want to create a `\u003cbutton\u003e` or `\u003ca\u003e` that points to the previous page (e.g. it would generate a URL such as the one in the `href` attribute of `\u003ca href=\"/users?page=1\u0026limit=10\"\u003ePrev\u003c/a\u003e` if `req.query.page` is `2`).\n\nPass an object for the value of `params` when you want to override querystring parameters \u0026ndash; such as for filtering and sorting (e.g. it would generate a URL such as the one in the `href` attribute of `\u003ca href=\"/users?page=1\u0026limit=10\u0026sort=name\"\u003eSort By Name\u003c/a\u003e` if `params` is equal to `{ sort: 'name' }`.\n\nNote that if you pass only one argument with a type of Object, then it will generate a `href` with the current page and use the first argument as the value for `params`.  This is useful if you only want to do something like change the filter or sort querystring param, but not increase or decrease the page number.\n\n[See the example below for an example of how implementation looks](#example).\n\n#### Arguments\n\n* `req` (**required**) \u0026ndash; the request object returned from Express middleware invocation\n\n#### Returned function arguments when invoked with `req`\n\n* `prev` (optional) \u0026ndash; a Boolean to determine whether or not to increment the hyperlink returned by `1` (e.g. for \"Next\" page links)\n* `params` (optional) \u0026ndash; an Object of querystring parameters that will override the current querystring in `req.query` (note that this will also override the `page` querystring value if `page` is present as a key in the `params` object) (e.g. if you want to make a link that allows the user to change the current querystring to sort by name, you would have `params` equal to `{ sort: 'name' }`)\n\n### paginate.hasPreviousPages\n\nWhen you use the `paginate` middleware, it injects a view helper Boolean called `hasPreviousPages` as `res.locals.hasPreviousPages`, which you can use in your views for generating pagination `\u003ca\u003e`'s or `\u003cbutton\u003e`'s \u0026ndash; this utilizes `req.query.page \u003e 1` to determine the Boolean's resulting value (representing if the query has a previous page of results)\n\n\n### paginate.hasNextPages(req)\n\nWhen you use the `paginate` middleware, it injects a view helper function called `hasNextPages` as `res.locals.hasPreviousPages`, which you can use in your views for generating pagination `\u003ca\u003e`'s or `\u003cbutton\u003e`'s \u0026ndash; if the function is executed, it returns a Boolean value (representing if the query has another page of results)\n\nBy default, the view helper `paginate.hasNextPages` is already executed with the inherited `req` variable, therefore it becomes a function capable of returning a Boolean when executed.\n\nWhen executed with `req`, it will return a function that accepts two required arguments called `pageCount` and `resultsCount`.\n\n#### Arguments\n\n* `req` (**required**) \u0026ndash; the request object returned from Express middleware invocation\n\n#### Returned function arguments when invoked with `req`\n\n* `pageCount` (**required**) \u0026ndash; a Number representing the total number of pages for the given query executed on the page\n\n### paginate.getArrayPages(req)\n\nGet all the page urls with limit.\n![petronas contest 2015-10-29 12-35-52](https://cloud.githubusercontent.com/assets/3213579/10810997/a5b0b190-7e39-11e5-9cca-fb00a2142640.png)\n\n#### Arguments\n\n* `req` (**required**) \u0026ndash; the request object returned from Express middleware invocation\n\n#### Returned function arguments when invoked with `req`\n\n* `limit` (**optional**) \u0026ndash; Default: 3, a Number representing the total number of pages for the given query executed on the page.\n* `pageCount` (**required**) \u0026ndash; a Number representing the total number of pages for the given query executed on the page.\n* `currentPage` (**required**) \u0026ndash; a Number representing the current page.\n\n\n## Example with mongoose ODM (see example 2 for Sequelize ORM)\n\n```js\n\n// # app.js\n\nconst express = require('express');\nconst paginate = require('express-paginate');\nconst app = express();\n\n// keep this before all routes that will use pagination\napp.use(paginate.middleware(10, 50));\n\napp.get('/users', async (req, res, next) =\u003e {\n\n  // This example assumes you've previously defined `Users`\n  // as `const Users = db.model('Users')` if you are using `mongoose`\n  // and that you are using Node v7.6.0+ which has async/await support\n  try {\n\n    const [ results, itemCount ] = await Promise.all([\n      Users.find({}).limit(req.query.limit).skip(req.skip).lean().exec(),\n      Users.count({})\n    ]);\n\n    const pageCount = Math.ceil(itemCount / req.query.limit);\n\n    if (req.accepts('json')) {\n      // inspired by Stripe's API response for list objects\n      res.json({\n        object: 'list',\n        has_more: paginate.hasNextPages(req)(pageCount),\n        data: results\n      });\n    } else {\n      res.render('users', {\n        users: results,\n        pageCount,\n        itemCount,\n        pages: paginate.getArrayPages(req)(3, pageCount, req.query.page)\n      });\n    }\n\n  } catch (err) {\n    next(err);\n  }\n\n});\n\napp.listen(3000);\n\n```\n\n## Example 2 with Sequelize ORM\n```js\n\n// # app.js\n\nconst express = require('express');\nconst paginate = require('express-paginate');\nconst app = express();\n\n// keep this before all routes that will use pagination\napp.use(paginate.middleware(10, 50));\n\napp.get('/users', async (req, res, next) =\u003e {\n\n  // This example assumes you've previously defined `Users`\n  // as `const Users = sequelize.define('Users',{})` if you are using `Sequelize`\n  // and that you are using Node v7.6.0+ which has async/await support\n\n  router.get(\"/all_users\", (req, res, next) =\u003e {\n    db.User.findAndCountAll({limit: req.query.limit, offset: req.skip})\n      .then(results =\u003e {\n        const itemCount = results.count;\n        const pageCount = Math.ceil(results.count / req.query.limit);\n        res.render('users/all_users', {\n          users: results.rows,\n          pageCount,\n          itemCount,\n          pages: paginate.getArrayPages(req)(3, pageCount, req.query.page)\n        });\n    }).catch(err =\u003e next(err))\n  });\n\n});\n\napp.listen(3000);\n```\n\n```pug\n\n//- users.pug\n\nh1 Users\n\n//- this will simply generate a link to sort by name\n//- note how we only have to pass the querystring param\n//- that we want to modify here, not the entire querystring\na(href=paginate.href({ sort: 'name' })) Sort by name\n\n//- this assumes you have `?age=1` or `?age=-1` in the querystring\n//- so this will basically negate the value and give you\n//- the opposite sorting order (desc with -1 or asc with 1)\na(href=paginate.href({ sort: req.query.age === '1' ? -1 : 1 })) Sort by age\n\nul\n  each user in users\n    li= user.email\n\ninclude _paginate\n```\n\n```pug\n\n//- _paginate.pug\n\n//- This examples makes use of Bootstrap 3.x pagination classes\n\nif paginate.hasPreviousPages || paginate.hasNextPages(pageCount)\n  .navigation.well-sm#pagination\n    ul.pager\n      if paginate.hasPreviousPages\n        li.previous\n          a(href=paginate.href(true)).prev\n            i.fa.fa-arrow-circle-left\n            |  Previous\n      if pages\n        each page in pages\n          a.btn.btn-default(href=page.url)= page.number\n      if paginate.hasNextPages(pageCount)\n        li.next\n          a(href=paginate.href()).next\n            | Next\u0026nbsp;\n            i.fa.fa-arrow-circle-right\n```\n\n\n## License\n\n[MIT][license-url]\n\n\n[npm-image]: https://img.shields.io/npm/v/express-paginate.svg?style=flat\n[npm-url]: https://npmjs.org/package/express-paginate\n[travis-image]: https://img.shields.io/travis/expressjs/express-paginate.svg?style=flat\n[travis-url]: https://travis-ci.org/expressjs/express-paginate\n[coveralls-image]: https://img.shields.io/coveralls/expressjs/express-paginate.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/expressjs/express-paginate?branch=master\n[downloads-image]: http://img.shields.io/npm/dm/express-paginate.svg?style=flat\n[downloads-url]: https://npmjs.org/package/express-paginate\n[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat\n[license-url]: LICENSE\n[slack-url]: https://join.slack.com/t/ladjs/shared_invite/zt-fqei6z11-Bq2trhwHQxVc5x~ifiZG0g/\n[slack-image]: https://img.shields.io/badge/chat-join%20slack-brightgreen\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpressjs%2Fexpress-paginate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexpressjs%2Fexpress-paginate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpressjs%2Fexpress-paginate/lists"}