Clone or download


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