Infinite Scroll in Laravel with Livewire

Infinite scrolling in Laravel

This tutorial is about the infinite scrolling in Laravel using Livewire in datatable setup. This is not going to be an actual datatable but a common HTML table styled with tailwend CSS. The main purpose of this post is not about styling stuff but to give an overview how you can achieve infinite scrolling. 

I will doing everything from scratch and will explain everything so that you can’t miss a thing. I hope you will learn a lot from this so let’s get started. 

First of all Install Laravel. 
If you don’t know how to install Laravel, you can read how to install Laravel here so,  install Laravel where you want to install it by,


[sourcecode language="plain"]composer create project laravel/laravel infinite-scroll-project[/sourcecode]

This will install Laravel project by the name infinit-scroll-project.

Configure the database credentials in .env file 

I would like to mention that Laravel does not provide auth scaffolding by default so we will have to generate some files manually.

We will include tailwind css from its Laravel posted page  for version 2.0 because there was issues with post css 8 and that cleared up a lot of issues. so, install npm by ,


[sourcecode language="plain"]npm install[/sourcecode]

Next we will run some commands in order to have tailwind installed in out project. 

[sourcecode language=”plain”]npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init

This will create tailwind.config.js file in the root directory of your project and basically  is a file where you want to extend styles, create styles, install plugins and add configuration of tailwind purge and by default the file looks like,

[sourcecode language=”js”]module.exports = {
content: [
theme: {
extend: {},
plugins: [],

so in the content it will look for any file ends with .blade, .vue or .js and will  look the classes within these files and not eliminate them in the production css file.

Next we need to acquire tailwind css within the webpack.mix.js file so insert this into your webpack.mix.js file like,

[sourcecode language=”js”]mix.js(“resources/js/app.js”, “public/js”)
.postCss(“resources/css/app.css”, “public/css”, [

Next copy the following code into your app.css file which is located in resources/css/app.css and run npm watch command

[sourcecode language=”css”]
@tailwind base;
@tailwind components;
@tailwind utilities;

As the tailwind is installed now the last thing before we go to actual coding to include the following code into your main page layout like app.blade.php or whatever your main layout file will be.

[sourcecode language=”plain”]


Now we will have to install Laravel Livewire with the following command,
[sourcecode language=”plain”]
composer require livewire/livewire
and include the following into your root file, in our case it is app.blade.php
[sourcecode language=”html”]


now that Livewire and tailwind are installed and configured next we want to seed some fake entries to the user table and we will use factory for this purpose.
By default there is user factory in the migration directory so we just want to use that in our DatabaseSeeder.php it like this,
[sourcecode language=”php”]
and then run the following command to migrate the tables into your database and the seed the data.
[sourcecode language=”php”]
php artisan migrate –seed
Now we want to create a livewire component with the following command,
[sourcecode language=”php”]
php artisan make:livewire Users
This command will create two files Users.php as a users class and Users.blade.php as view component.

Now that we have seeded the data and created livewire component let’s create a route in web.php file as,
[sourcecode language=”php”]
use App\Http\Livewire\Users;
Route::get(‘/’, Users::class);

you can do whatever you like to redirect your route. For the simplicity I redirected the main base route to the livewire component class.

Now paste the following code in app.blade.php and leave it as it is,
[sourcecode language=”php”]





This is the same app.blade.php file I just inserted some code.
The slot variable is the variable with with which the livewire component data will be slotted.

Now paste the following code to the Livwire component class which is app/Livewire directory Users.php as,

[sourcecode language=”php”]
loadrecords += 15;

public function mount()
$this->totalRecords = User::count();

public function render()
return view(‘livewire.users’)
User::orderBy(‘created_at’, ‘desc’)

And paste the following code in Users.blade.php
[sourcecode language=”php”]


@foreach ($users as $user)

last) id=”last_record” @endif>


Name Email Created At
{{ $user->name }} {{ $user->email }} {{ $user->created_at->diffForHumans() }}

@if ($loadrecords >= $totalRecords)

No Remaining Records!


const lastRecord = document.getElementById(‘last_record’);
const options = {
root: null,
threshold: 1,
rootMargin: ‘0px’
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {


Now that our code is completed lets explain what actaully is doing,
The render function just take the records from users tables that we seeded by the limit of 15 as we have passed loadrecords variable to the limit function.
In the blade component there is if condition if the record will be last then we assign the id to the table tr as last_record with which we will observe the scroll observer.
In the script we take the last record element as it will only be 1 at time on the screen, we then define our options which are,
root, that is used as the viewport for checking the visibility of the target which is must be the ancestor of the target default to the browser viewport if nor specified or null and we have set it to null so the target is browser viewport which means if the last element will come to viewport the observer will be triggered,
threshold is either a single number or array of numbers which indicates at what percentage of the target visibility the observer call back should be executed, in our case 1 means if 100 percent of the target is visible within the element specified by the root option the callback will be invoked.
Thank you reading this and I hope you must have learned something new or has solved your problem.

Previous Post
Next Post


Avatar for Ahmad Rehman
Ahmad Rehman

informative blog.

Avatar for David

JavaScript observers … Nice Use Case

Avatar for cryptofear

Reading your article helped me a lot and I agree with you. But I still have some doubts, can you clarify for me? I’ll keep an eye out for your answers.

Leave a Reply