Infinite Scroll plugin screenshot
Dark mode ready
Multilingual support
Supports v5.x

Infinite Scroll by asign

Community

Infinite scroll and a "Load more" button for resources, relation managers and table widgets.

Tags: Tables
Supported versions:
5.x
asign avatar Author: asign

Package health

Automated checks of this plugin's Composer package

100 / 100
Security 100
Maintenance 100
Ecosystem 100
15 checks
  • Passed: GitHub Actions pinned to SHA
  • Skipped: GitLab CI includes pinned to SHA
  • Passed: Open security advisories
  • Passed: Dependabot PR responsiveness — No open Dependabot PRs.
  • Skipped: Renovate MR responsiveness
  • Passed: Dependabot or Renovate configured
  • Passed: Dependency update cooldown configured
  • Passed: Provides a security policy
  • Passed: Abandoned or archived — No consulted source marks the package abandoned (packagist, github).
  • Passed: Commit and release recency — Active: last commit 0 days ago; last release 0 days ago.
  • Passed: composer.lock not committed by library — composer.lock is absent from the released dist archive.
  • Passed: Dist archive is lean
  • Passed: Current Laravel version supported — Package dependencies resolve together with current Laravel 13.0.
  • Passed: Current PHP version supported — Constraint ^8.3 supports current PHP 8.5.
  • Skipped: Current Symfony version supported
Third-party plugin. This is built by the community, not the Filament team. Filament does not review, endorse, or vet the security of plugins outside the filament/ namespace. Review the source and install at your own risk. Found malware or an unresolved security issue the author won't address? Report it .
Powered by Plumb Last scanned 12 hours ago

Documentation

Stand With Ukraine Latest Version on Packagist Tests Total Downloads License Plumb score

Filament Infinite Scroll

Infinite scroll and a "Load more" button for Filament tables, with one line:

return $table->columns([...])->infiniteScroll();

Filament 5 offers default, simple and cursor pagination only. People keep asking for a table that just grows (#12764, #5692), and the one existing plugin supports Filament 3 only. This one is built for Filament 5.

#Screenshots

Scroll mode loading the next chunk

Everything loaded

#Requirements

  • PHP 8.3+
  • Filament 5 (Livewire 4)
  • Laravel 12 or 13

#Installation

composer require asignua/filament-infinite-scroll
php artisan filament:assets

The service provider is auto-discovered. filament:assets publishes a 1 KB stylesheet that hides Filament's own pager on these tables and lays out the footer. Optionally publish the config:

php artisan vendor:publish --tag=filament-infinite-scroll-config

#Usage

infiniteScroll() is a macro on Filament\Tables\Table. Call it in any table(): a resource, a relation manager, a table widget, a page with InteractsWithTable.

use Asignua\FilamentInfiniteScroll\InfiniteScrollMode;

public static function table(Table $table): Table
{
    return $table
        ->columns([...])
        ->infiniteScroll(
            perPage: 25,                          // rows per chunk (first and every next one)
            mode: InfiniteScrollMode::Scroll,     // or 'scroll' | 'button'
            maxRecords: 500,                      // false removes the ceiling
            rootMargin: 300,                      // px before the end at which the next chunk is requested
        );
}

Every argument is optional and defaults to config/filament-infinite-scroll.php.

Mode Behaviour
scroll The next chunk loads when the end of the table scrolls into view. If the new rows do not push the end out of view (a tall screen) the next chunk follows at once.
button A "Load more" button under the table.

Under the rows the table shows "Showing 25 of 120", then "All 120 records are loaded" when the list is complete. A table with fewer rows than one chunk shows no footer at all, and no stock pager either. Counts are formatted for the current app locale.

#How it works

Filament's table is one query and one Blade view. The plugin forks neither.

  1. The page size grows. The table's $tableRecordsPerPage (a public Livewire property) goes 25 → 50 → 75 …, the page stays 1. Because it is still a single paginated query, selection, "select all", bulk actions, grouping, summaries and record actions work exactly as on a normal page.
  2. A global Livewire hook answers the infiniteScrollLoadMore call, so no trait or base class has to be added to your pages, relation managers or widgets. The same hook keeps the page size inside [one chunk, ceiling] and pins the page number to 1. The value is client-writable, so the server also remembers the size it issued last (in the checksummed memo) and never lets the browser raise it: the list grows only one chunk per call, with or without a ceiling.
  3. A render hook (TablesRenderHook::CONTENT_AFTER) draws the footer: the status line, the x-intersect sentinel or the button (<x-filament::button>).
  4. Reset on change. A signature of the search, column searches, filters, sort, grouping and the active tab is kept in the Livewire memo (checksummed with the snapshot). When it changes the list starts over from the first chunk.

Scroll position is preserved: Livewire morphs the new rows in below the existing ones.

#Trade-offs

  • Rows are re-queried: loading chunk 4 runs LIMIT 100, not LIMIT 25 OFFSET 75. This is what keeps selection and actions simple, and it is cheap up to the ceiling. It is why there is a ceiling.
  • The table needs a total (COUNT(*)), like Filament's default pager. Cursor and simple pagination are not used.
  • The DOM grows with the list. Past a few hundred rows the browser, not the database, becomes the limit.

#Configuration

config/filament-infinite-scroll.php:

Key Default
per_page 25 Rows per chunk.
mode 'scroll' 'scroll' or 'button'.
max_records 500 The most rows kept on the page; null removes the ceiling.
root_margin 300 Pixels before the end at which the next chunk is requested.

When the ceiling is reached the footer says "Showing the first 500 of 12,345 records. Use search or filters to narrow the list." and loading stops.

#Gotchas

  • infiniteScroll() sets paginated(), the page-size options, the pagination mode and persistRecordsPerPageInSession(false). Do not set them yourself afterwards.
  • The "records per page" select disappears: the page size is the plugin's state.
  • Do not use deferLoading() plus a custom records() data source: the plugin needs a length-aware paginator and draws nothing otherwise.
  • Reordering (reorderable()) uses Filament's own rules for pagination while reordering.
  • Run php artisan filament:assets after upgrading, or the stock pager shows next to the footer.

#Translations

English, Ukrainian, German, Spanish, French, Italian, Dutch, Polish, Brazilian Portuguese and Turkish, under the filament-infinite-scroll::infinite-scroll namespace. A test keeps every language in step with the English keys and placeholders.

#AI agents

The package ships Laravel Boost guidelines (resources/boost/guidelines/core.blade.php) so a coding agent uses the macro correctly.

#Testing

composer install
vendor/bin/phpunit
vendor/bin/phpstan analyse --memory-limit=1G
vendor/bin/pint --test

The suite runs on Orchestra Testbench with a workbench/ panel: a resource, a relation manager and a table widget.

The suite checks what the server renders (data-has-more, data-loaded, the footer's wire:key), not the Alpine code that reads it. Before a release, check scroll mode by hand in a browser:

  1. A tall viewport with many records: the list fills the screen on its own and stops once the footer is out of view.
  2. Scroll to the ceiling: loading stops and the "Showing the first N" notice appears; no further requests in the network tab.
  3. With the footer still in view (all or the ceiling loaded), sort or filter: the list starts over and, on a short page, loads the next chunk again without scrolling.
  4. Make a load request fail (go offline): the footer does not retry in a loop.

#Changelog

See CHANGELOG.md.

#License

The MIT License (MIT). See LICENSE.md.

The author

asign avatar Author: asign

asign is a small web-dev company from Lviv, Ukraine. We build business applications on Laravel and Filament — CRMs, automation systems for standard and non-standard business processes, booking and content management systems, including our own Filament-based CMS. We open-source the parts that prove useful beyond a single project

Plugins
15
Stars
6

From the same author