Skip to content

Background recache token (__recache) leaks into pagination links and is baked into the static cache #15294

Description

@mgtcampbell

Bug description

Bug description

With STATAMIC_BACKGROUND_RECACHE=true, any page rendered by a background recache request emits pagination links that carry the __recache token:

<li><a href="https://example.com/resources/news?__recache=f452fe13…&amp;page=2">2</a></li>

That HTML is then written to the static cache, so the token is served to every subsequent anonymous visitor until something regenerates the page without it.

Cause. Statamic\Extensions\Pagination\LengthAwarePaginator::withQueryString() overrides Laravel's implementation and appends the raw query string:

// src/Extensions/Pagination/LengthAwarePaginator.php
public function withQueryString()
{
    $this->appends(request()->query());

    return $this;
}

Laravel's version routes through Paginator::$queryStringResolver, which is the documented seam for filtering query params. Because the override bypasses it, the usual workaround (Paginator::queryStringResolver(...)) silently has no effect — the closure is never called.

How to reproduce

  1. Statamic 6 site with static caching enabled (half or full) and STATAMIC_BACKGROUND_RECACHE=true.
  2. A template with a paginated listing:
    {{ collection:blog paginate="12" as="posts" }}
      {{ posts }}{{ title }}{{ /posts }}
      {{ paginate }}{{ auto_links }}{{ /paginate }}
    {{ /collection:blog }}
  3. Cause that page to be recached in the background — save an entry, or run php please static:warm.
  4. Request the page as an anonymous visitor and view source. The pagination hrefs contain ?__recache=<token>&page=N.

Note this is intermittent by nature: an ordinary (untokened) request regenerates the page with clean links, so the token is only present while the cached copy is the one produced by a recache request. On a site with frequent content edits it reappears regularly.

Logs

Environment

- Statamic 6.29.0 PRO
- Laravel 13.29.0
- PHP 8.4.19
- Static caching: half measure
- `STATAMIC_BACKGROUND_RECACHE=true`

Installation

Other (please explain)

Additional details

Existing site, upgraded from Statamic 5. Only started once background recache was then enabled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions