---
title: "Sorting — Query Builder for Laravel | Roundly"
description: "Allow-list sort fields, map public names to columns, sort by several columns and set a default order."
url: https://roundly-consulting.com/open-source/docs/query-builder-for-laravel/sorting
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Query Builder for Laravel](https://roundly-consulting.com/open-source/docs/query-builder-for-laravel.md)

# Sorting

Declare sortable fields with allowedSorts(). A bare string becomes AllowedSort::field(); AllowedSort::custom() plugs in your own Sort:

```php
use RoundlyConsulting\QueryBuilder\AllowedSort;

->allowedSorts(
    'title',                                     // shorthand for AllowedSort::field('title')
    AllowedSort::field('popularity', 'views'),   // sort=-popularity → ORDER BY views DESC
    AllowedSort::custom('length', new TitleLengthSort),
)
->defaultSort('-created_at')                     // applied only when no sort param is present
```

## Sort syntax

- sort=title sorts ascending; a leading - (sort=-title) sorts descending.
- sort=-created\_at,name applies several sorts, left to right.
- A repeated column collapses to its first occurrence — sort=title,-title sorts by title ascending, once.
- At most limits.max\_sorts columns are applied (default 5), counted after duplicates are removed. Only allow-listed sorts count, so in ignore mode an unknown token never crowds out a valid one behind it.

## Default sort

defaultSort() takes the same syntax — a - prefix and comma multi-sort — and runs only when the request names no sort — or, in ignore mode, none the allow-list knows. A default token that matches an allowed sort uses it (including its internal column or custom sort); any other token is ordered as a plain column, so a default does not have to be allow-listed:

```php
QueryBuilder::for(Post::class)
    ->allowedSorts('title', AllowedSort::field('popularity', 'views'))
    ->defaultSort('-popularity,id');   // ORDER BY views DESC, id ASC

// ?sort=title → ORDER BY title ASC (the default is skipped)
```

## Method reference

| Method | Effect |
| --- | --- |
| `AllowedSort::field($name, $internalName = null)` | `orderBy(<column>, <direction>)` |
| `AllowedSort::custom($name, Sort $sort, $internalName = null)` | Delegates to your Sort implementation. |
| `defaultSort(string $sort)` | Order used when the request has no sort param. |

Directions are the SortDirection enum: Ascending (asc) and Descending (desc); SortDirection::fromToken('-title') resolves a token’s direction.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/query-builder-for-laravel.md)
