In Salesforce, LWC is frequently employed to retrieve substantial data volumes from the Salesforce server and display them on the screen using either the base lightning-datatable or a customized HTML table.
In this tutorial, you’ll discover how to establish a custom JavaScript pagination mechanism using the lightning data table component to paginate extensive datasets. The example involves creating a paginated display of standard contact records in Salesforce. Additionally, users can modify the page size (number of records per page) with predefined options, such as 5, 10, 15, and more.
Output of Salesforce LWC Datable-Table Pagination Example
Following is the result of creating pagination for lightning data table in salesforce using lwc applications.

Lightning Web Component /Apex Controller – Source Code
Apex Controller – ContactDataController.cls
public with sharing class ContactDataController {
// apex method to fetch contact records from salesforce database
@AuraEnabled
public static list<Contact> fetchContacts(){
list<Contact> lstContact = new list<Contact>();
for(Contact con : [SELECT id,name,email,phone,title FROM Contact LIMIT 5000]){
lstContact.add(con);
}
return lstContact;
}
}
Html File- dataTableWithPagination.html
<template>
<template if:true={records}>
<!--LIGHTNING DATATABLE-->
<div style="height:400px">
<lightning-datatable key-field="Id" data={recordsToDisplay} hide-checkbox-column="true" columns={columns}></lightning-datatable>
</div>
<div class="slds-grid slds-grid_vertical-align-center slds-grid_align-spread" style="padding-top: 0.5em;">
<!--RECORDS PER PAGE-->
<div class="slds-col">
<div class="slds-list_inline slds-p-bottom_xx-small">
<label class="slds-text-color_weak slds-p-horizontal_x-small" for="recordsPerPage">Page Size:</label>
<div class="slds-select_container">
<select class="slds-select" id="recordsPerPage" onchange={handleRecordsPerPage}>
<template for:each={pageSizeOptions} for:item="option">
<option key={option} value={option}>{option}</option>
</template>
</select>
</div>
</div>
</div>
<!--PAGE NAVIGATION-->
<div class="slds-align_absolute-center" style="height:5rem">
<lightning-button disabled={bDisableFirst} icon-name="utility:jump_to_left" label="First" class="slds-p-horizontal_x-small" alternative-text="first page" onclick={firstPage}></lightning-button>
<lightning-button disabled={bDisableFirst} icon-name="utility:chevronleft" label="Previous" alternative-text="Previous" onclick={previousPage}></lightning-button>
<span class="slds-badge">Showing {pageNumber} of {totalPages} Page(s)</span>
<lightning-button disabled={bDisableLast} icon-name="utility:chevronright" label="Next" alternative-text="Next" onclick={nextPage} class="slds-p-horizontal_x-small" icon-position="right"></lightning-button>
<lightning-button disabled={bDisableLast} icon-name="utility:jump_to_right" label="Last" alternative-text="last page" onclick={lastPage} icon-position="right"></lightning-button>
</div>
<!--TOTAL RECORDS-->
<div class="slds-clearfix">
<div class="slds-float_right">
<span class="slds-badge"> Total Records: {totalRecords}</span>
</div>
</div>
</div>
</template>
</template>
JavaScript File – dataTableWithPagination.js
/*
API : 52
Source : lwcFactory.com
*/
import {LightningElement} from 'lwc';
//Import apex method
import fetchContacts from '@salesforce/apex/.fetchContacts';
export default class DatatableWithPagination extends LightningElement {
// JS Properties
pageSizeOptions = [5, 10, 25, 50, 75, 100]; //Page size options
records = []; //All records available in the data table
columns = []; //columns information available in the data table
totalRecords = 0; //Total no.of records
pageSize; //No.of records to be displayed per page
totalPages; //Total no.of pages
pageNumber = 1; //Page number
recordsToDisplay = []; //Records to be displayed on the page
get bDisableFirst() {
return this.pageNumber == 1;
}
get bDisableLast() {
return this.pageNumber == this.totalPages;
}
// connectedCallback method called when the element is inserted into a document
connectedCallback() {
// set datatable columns info
this.columns = [{
label: 'Name',
fieldName: 'Name'
},
{
label: 'Email',
fieldName: 'Email'
},
{
label: 'Phone',
fieldName: 'Phone'
},
{
label: 'Title',
fieldName: 'Title'
},
];
// fetch contact records from apex method
fetchContacts()
.then((result) => {
if (result != null) {
console.log('RESULT--> ' + JSON.stringify(result));
this.records = result;
this.totalRecords = result.length; // update total records count
this.pageSize = this.pageSizeOptions[0]; //set pageSize with default value as first option
this.paginationHelper(); // call helper menthod to update pagination logic
}
})
.catch((error) => {
console.log('error while fetch contacts--> ' + JSON.stringify(error));
});
}
handleRecordsPerPage(event) {
this.pageSize = event.target.value;
this.paginationHelper();
}
previousPage() {
this.pageNumber = this.pageNumber - 1;
this.paginationHelper();
}
nextPage() {
this.pageNumber = this.pageNumber + 1;
this.paginationHelper();
}
firstPage() {
this.pageNumber = 1;
this.paginationHelper();
}
lastPage() {
this.pageNumber = this.totalPages;
this.paginationHelper();
}
// JS function to handel pagination logic
paginationHelper() {
this.recordsToDisplay = [];
// calculate total pages
this.totalPages = Math.ceil(this.totalRecords / this.pageSize);
// set page number
if (this.pageNumber <= 1) {
this.pageNumber = 1;
} else if (this.pageNumber >= this.totalPages) {
this.pageNumber = this.totalPages;
}
// set records to display on current page
for (let i = (this.pageNumber - 1) * this.pageSize; i < this.pageNumber * this.pageSize; i++) {
if (i === this.totalRecords) {
break;
}
this.recordsToDisplay.push(this.records[i]);
}
}
}
Meta xml file – dataTableWithPagination.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>52.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__HomePage</target>
<target>lightning__Tab</target>
</targets>
</LightningComponentBundle>
Explanation:
The “pageNumber” is initialized with a value of 1, signifying that when the Lightning Web Component (LWC) is loaded, it will exhibit the first page as the current page. The number of items per page is determined by the “pageSize” JavaScript property, which is set to the first index item [5] of the ‘pageSizeOptions’ list.
The “totalRecords” JavaScript property indicates the total number of records returned from the Apex controller. The “recordsToDisplay” array property is utilized to filter and store the records for the current page when pagination changes. The “pageSizeOptions” property contains predefined options for the page size drop-down, and you can adjust the default values according to your requirements.
Within the JavaScript file, a common “paginationHelper()” function is implemented. This function calculates the paginated records for the current page based on the total number of pages and the current page number in context.
