Swiftpack.co - Package - nodes-vapor/paginator

Paginator πŸ“„

Swift Version Vapor Version Circle CI codebeat badge codecov Readme Score GitHub license

Query pagination for Vapor and Fluent.

GIF of paginator

πŸ“¦ Installation

Update your Package.swift file.

.Package(url: "https://github.com/nodes-vapor/paginator", majorVersion: 0)

Getting started πŸš€

Paginator does most of the hard work for you. Create and return a paginated Model like so:

import Vapor
import Paginator

drop.get("models") { req in
    // returns a pagination of 10 `MyModel`s.
    return try MyModel.paginator(10, request: req)

Rendering views with πŸƒ

What would pagination be without handy-dandy view rendering? Nothing. Before you can begin rendering paginators, you need to register the custom tag with your droplet. We have a Provider that will register the tag for you.


import Vapor
import Paginator

let drop = Droplet()
try drop.addProvider(PaginatorProvider.self)

Good! Now, pass a Paginator to your πŸƒ templates like so:


drop.get("/") { req in
    let posts = try Post.paginator(10, request: req)
    return try drop.view.make("index", [
        "posts": try posts.makeNode()

Inside of your πŸƒ template you can iterate over your paginator's entities by accessing the paginator's data field.


#loop(posts.data, "post") {
<div class="post">
  <span class="date">#(post.date)</span>
  <span class="text">#(post.content)</span>

Finally, the piΓ¨ce de rΓ©sistance: navigation controllers using paginators and πŸƒ.



Overriding the page query key

If you don't like the query key page, you can override it at the paginator callsite.

return try MyModel.paginator(10, pageName: "slide", request: req)

The query string will now have the value ?slide=1&count=10

Overriding the data JSON key

If you wish to be more explicit with the name of your data, you can override the default JSON key.

return try MyModel.paginator(10, dataKey: "my_models")

The JSON response will now look like:

    "my_models": [
        // models here

    "meta": {
        "paginator": {

Overriding the deafult response formatter

In case you've defined specific formatters for your data, you can override the default formatter

let signups: Paginator<SignUp> = try query.paginator(25, request: request) { signups in
            return try signups.map { signup in
                return try signup.makeNode()

Using Bootstrap 4

By default, Paginator prints Bootstrap 3-compatible HTML in Leaf, however it is possible to configure it to use Bootstrap 4. You can add a paginator.json file to your Config directory with the values:

    "useBootstrap4": true

You can alternatively manually build the Paginator Provider and add it to your Droplet:

let paginator = PaginatorProvider(useBootstrap4: true)

Specifying an Aria Label

The Paginator HTML adds in Aria labels for accessibility options, such as screen readers. It is recommended that you add a label to your paginator to assist this. This can be done in the same way as the Bootstrap 4 options. Either in paginator.json:

    "paginatorLabel": "Blog Post Pages"

Or manually:

let paginator = PaginatorProvider(paginationLabel: "Blog Post Pages")

The two configurable options (label and Bootstrap 4) can obviously be combined.

πŸ† Credits

This package is developed and maintained by the Vapor team at Nodes. The package owner for this project is Siemen.

πŸ“„ License

This package is open-sourced software licensed under the MIT license


Stars: 33
Help us keep the lights on


3.0.0-beta.2 - Sep 6, 2018


  • Support for overwriting the count when using the OffsetPaginator on QueryBuilder. This is helpful in cases where you're doing complex queries and you need to control how the count is being calculated.
  • Support for overwriting the count when using the OffsetPaginator on arrays.


  • Instead of having to make a paginator for then to transform its content, you can now transform your content (coming from an array or a QueryBuilder) before calling paginate. This removes the need for the intermediate instance for defining the type of the (first) paginator.

⚠️ This is a breaking release

3.0.0-beta.1 - Aug 27, 2018


  • Rewritten for Vapor 3 πŸŽ‰

2.0.0 - Nov 8, 2017


  • Statically configure paginator key

1.1.3 - Nov 2, 2017


  • Made init with query parameter public

1.1.2 - Jul 25, 2017

  • relaxes protocol restriction on Entity from NodeConvertible to NodeRepresentable