UI Bakery Docs
RoadmapRelease notesSign In
  • 👋Welcome to UI Bakery!
  • 🌟Overview
    • 💡Video intro
    • ✨Main features
    • 🔖Glossary
  • 🛠️Getting started
    • Create an application
    • Build UI
      • Data mocking methods
    • Link components
    • Connect a data source
    • Load data
    • Bind data to UI
    • Transform data with JavaScript
      • Data mapping & transforming
    • Change component data
    • Send a form
    • Create a filter
    • Note on debugging
    • Deploy your application & invite users
  • 📌Concepts
    • Components
      • Component basics
      • Component methods
      • Components best practices
        • Input validation
        • Linking a Table to a Form/Detail
        • Using a single Form to add and update data
        • Searching Table based on input value
        • Configuring server-side pagination
        • Managing Date object time zones
        • Role-based Menu component items
        • Field types & types recognition
        • Expanding component to fit screen/container
        • Controlling component's visibility
    • Custom components
      • Unrestricted custom components
    • Data sources
      • Data source environments
      • Connecting local database via ngrok
      • SSH Tunneling
    • Actions
      • Actions basics
        • Calling actions from code
      • Actions management & shortcuts
      • Actions settings
      • Actions library
      • Server actions
      • Logs and debugging
    • UI Bakery variables
    • State variables
    • Local storage
    • Modules
    • Custom JavaScript
      • JavaScript files
    • Workspace management
      • Account & workspace
      • Seats & Shared permission groups in UI Bakery
      • Roles in UI Bakery
      • Role permissions
      • Explore the interface
      • App environments
        • Release management
      • Audit logs
      • Multi-factor authentication
    • Export & import an app
    • Mobile layout
    • Theme editor
      • Changing theme from the app
    • UI Bakery source control
      • Git controls overview
      • Migrating your app model to the latest version
  • ⚡How-tos
    • File management
      • Working with PDF files
      • CSV import & export
      • Uploading files using methods
      • Displaying files from Google Drive and Dropbox
      • Parsing and sending XML
    • Styling
      • Modifying components with CSS
    • Layout & navigation
      • Adding navigation to application
      • Reading query params from URL
      • Hiding UI Bakery loader in the Embedded mode
    • Data
      • Managing user data with the {{user.email}} variable
      • Using JS libraries
        • Internationalization (i18n) & Localization: Translating UI Bakery Apps
      • Implementing row-level security
      • Copying to clipboard
    • Custom code
      • Communicating with external sites via Iframe
      • Implementing custom app hotkeys
      • Retrying API with HTTP status code 202
  • 🔎Extras
    • UI Bakery Automations
      • Environment and release strategy
      • Git in automations
      • Using external Node libraries
    • UI Bakery Database
      • Database migration
  • 💻On-premise
    • UI Bakery on-premise
    • Install & update
      • Installing on-premise
        • Azure virtual machine
        • Azure container instance
        • AWS EC2 instance
        • Google Cloud Compute Engine VM instance
        • DigitalOcean 1-click droplet
        • Manual w/ docker compose
        • Manual w/ docker run
        • Windows installation
        • Kubernetes
          • AWS EKS with Fargate
          • Scaling and resource optimization
      • Troubleshooting installation errors
      • Updating on-premise
      • Updating license key
      • Updating environment variables
      • Recommendations
        • Architecture overview
        • UI Bakery in production
        • Resource optimization
        • Running a standalone database instance
        • Generating custom secrets
    • On-premise features
      • External analytics
      • Branding
      • Embedding
      • SCIM 2.0
      • Instance API
      • Activating features under a feature flag
    • Additional configurations
      • Health check API
      • Email configuration
      • Google Sheets connection setup
      • Salesforce connection setup
      • Azure blob storage configuration
      • Adding python backend code to existing installation
      • UI Bakery Postgres
    • Networking & security
      • Setting up a domain name
      • Configuring custom certificate authority
      • Custom base URL
      • Getting requests to the local network
      • Setting up SSL on Ubuntu
    • SSO
      • OpenID
        • Google OAuth2
        • Okta ODIC
        • Azure AD OAuth2
        • Token refresh
      • SAML
        • Okta SAML
        • Azure AD SAML
      • Role synchronization
      • Multiple SSO
      • Logout redirect
      • Troubleshooting
    • Git source control
      • Manage multi-instance deployment
      • Custom PR URL
      • Automate GitHub releases
      • Automate GitLab releases
      • Automate Bitbucket releases
    • Environment variables
  • 📚Reference
    • Data security measures
    • Improving app security
    • ✨AI Assistant
    • List of Components
      • S3 file uploader
      • Azure Blob Storage file uploader
      • Accordion
      • Alert
      • Avatar
      • Boolean
      • Breadcrumbs
      • Bubble map
      • Button
      • Card
      • Chart
      • Chat
      • Checkbox
      • Collapsible card
      • Color picker
      • Composite form
      • Container
      • Context menu button
      • Currency
      • Currency input
      • Date picker
      • Date & time
      • Date & time picker
      • Detail
      • Divider
      • Email input
      • Embedded App
      • File
      • File dropzone
      • File picker
      • Flex container
      • Form
      • Frame drawer
      • Grid view
      • Heading
      • Horizontal menu
      • Icon
      • iFrame
      • Image
      • Image picker
      • JSON editor
      • JSON viewer
      • Link
      • List view
      • Map
      • Menu
      • Metric
      • Modal
      • Multi-select
      • Number
      • Number input
      • Password input
      • PDF viewer
      • Percent
      • Pop-up form
      • Progress bar
      • QR code
      • Radio
      • Range slider
      • Rating
      • Reusable header
      • Reusable sidebar
      • Select
      • Signature
      • Slider
      • Steps
      • Stepper
      • Table
        • Conditional formatting based on cell value
        • Display name instead of ID for relation
        • Row context referencing
        • Select multiple table rows
        • How to Highlight Text in a Table Using mark.js
      • Tabs
      • Tabset
      • Tags
      • Text
      • Text annotate
      • Text input
      • Time picker
      • Toggle
      • Tree component
      • Video
      • Dynamic structure properties
      • Card (deprecated)
      • Input (deprecated)
    • Upgrading components
    • List of Data sources
      • Airtable
      • AWS S3
        • S3 compatible endpoints (DigitalOcean spaces)
      • AWS API
      • AWS Athena
      • AWS DynamoDB
      • AWS Lambda
      • AWS Redshift
      • Azure Blob Storage
      • Big Query
      • Databricks
      • Exasol
      • Firestore, Firebase Auth & Realtime DB
        • Firebase authentication
        • Managing database data
        • Firebase client-side SDK
        • Firebase libraries
      • GitHub
      • Google Sheets
      • GraphQL
      • HTTP API
        • API Authentication
      • HubSpot
      • Twilio
      • JDBC
      • MariaDB
      • MongoDB
      • MySQL
      • OpenAI
      • OpenAPI
      • Oracle
      • PostgreSQL
      • Presto
      • Redis
      • Salesforce
      • SAP Hana
      • SMTP
      • SendGrid
      • Slack
      • Snowflake
      • Spanner
      • SSH
      • Stripe
      • SQL Server
      • Supabase
      • UI Bakery AI
    • List of Action steps
      • Azure Blob Storage query
      • Bulk Create Rows
      • Bulk Delete Rows
      • Code step
      • Condition step
      • Create Row
      • Delete Row
      • DynamoDB request
      • Execute another action
      • Firebase query
      • Generate file
      • GraphQL query
      • HTTP request
      • Interval step
      • Load Table
      • Load Row
      • Loop action
      • MongoDB command
      • Navigation action
      • Open API request
      • Python backend code
      • Redis command
      • S3 query
      • Save to local storage
      • Save to state
      • Show notification
      • Slack messages
      • SMTP request
      • SSH command
      • SQL query
        • Writing SQL Queries
      • Update Row
    • Troubleshooting techniques
    • Performance optimization
Powered by GitBook

© 2025 UI Bakery

On this page
  • Page-based pagination
  • Cursor-based pagination
  • Total row count
  • Server-side filtering and sorting
  • Filtering
  • Sorting
  • Troubleshooting

Was this helpful?

Export as PDF
  1. Concepts
  2. Components
  3. Components best practices

Configuring server-side pagination

PreviousSearching Table based on input valueNextManaging Date object time zones

Last updated 1 month ago

Was this helpful?

If your dataset contains thousands of records, you may struggle with load time and app performance. To improve performance, you can configure server-side pagination allowing you to load only the records on the current page.

Here, we talk about the component. But the guide is also suitable for and components.

It's important to keep in mind that when server-side pagination is enabled, table inline filters and sorting don't work automatically and need to be .

In this article, we'll explore two types of server-side pagination:

Page-based pagination

To implement page-based server-side pagination, follow the steps below:

  1. For the Table component, select the Server side pagination checkbox in the right side panel.

  2. Next, create a new action of the SQL Query type and use the {{ui.table.pageSize}} and {{ui.table.paginationOffset}} variables to control the data you need to load:

SELECT * FROM users LIMIT {{ui.table.pageSize}} OFFSET {{ui.table.paginationOffset}};

With these variables, you can configure your action to only load the page that the table requests, by sending the pageSize and paginationOffset variables to your API or Load table action.

  1. Now, assign this action to the On Page Change trigger of the Table to ensure the data is reloaded with each table page navigation.

  2. Finally, set the Table's Show loading setting to true while your SQL Query action is loading - add the {{actions.loadData.loading}} variable.

Done! Now the Table will display only the records for a specific page.

Cursor-based pagination

Let's review cursor-based pagination based on the Stripe API example. Say you want to select a list of customers from Stripe API. To do that, follow the instruction below:

  1. For the Table component, select the Server side pagination checkbox in the right side panel.

  2. Next, create a new action of the HTTP Request type and specify the {{ui.table.pageSize}} and {{ui.table.afterCursor}} variables in JS mode - Query Params.

const param = {
	limit: {{ui.table.pageSize}},
};
if ({{ui.table.afterCursor}}) {
	param.starting_after = {{ui.table.afterCursor}};
}

return param;

With these variables, you can configure your action to only load the page that the table requests, by sending pageSize and afterCursor variables to your API.

  1. Now, in Table settings, set the following:

  • {{_.last(actions.customers.data.data).id}} to the Next cursor field (the identifier used for the next set of results),

  • {{actions.customers.data.has_more}} to the Has next page field to enable or disable the next page button according to API info, where actions.customers is the action we created in Step 2.

  1. Assign your HTTP Request action to the On Page Change trigger of the table to ensure the data is reloaded with each table page navigation.

Total row count

By default, the Table doesn't know the total number of items and can't disable the Next page button if the limit is reached. To display the total item count and make the table more intuitive, you can set the Total row count setting. Based on it, the number of pages will be calculated and displayed according to the items per page.

To retrieve the total row count, you simply need to create an action that will retrieve the total number of items or get this info from the API you are using. For example, you can use an action of the SQL Query type:

SELECT COUNT(*) AS AMOUNT FROM orders;

When using a Load Table action type, you can obtain the row count using {{actions.loadData.res.total}}. In this case, you may not need the additional action to calculate the total number of records and you can use this property to show the pager.

Server-side filtering and sorting

When server-side pagination is enabled, table filters and sorting don't work automatically, as the Table cannot filter and sort the data while it's being loaded page by page.

Filtering

To configure server-side filters, you can use the {{ui.table.filters}} variable in your action to send this data to your API/SQL Query or Load Table action.

When using filters, make sure the SQL query is configured in a way that it returns all records when the filters are empty, instead of trying to search for empty records. For instance, for most SQL databases you would need to use a LIKE operator combined with the % sign, which represents zero, one, or multiple characters:

select
  *
from
  users
where
  users.name like CONCAT ('%', {{ ui.table.filters.name}}, '%')
limit
  {{ui.table.pageSize}}
offset
  {{ui.table.paginationOffset}}

And don't forget to assign the action with the filter variable to the On Filters Change trigger.

Sorting

To enable sorting, use the {{ui.table.sortColumn}} and {{ui.table.sortDirection}} variables in your action.

After you disable the Prepared statement setting, your SQL Query will look like this:

select
  *
from
  users
where
  users.name like CONCAT ('%', '{{ ui.table.filters.name }}', '%')
order by
  {{ui.table.sortColumn ?? 'id'}} {{ui.table.sortDirection ?? 'asc'}}
limit
  {{ui.table.pageSize}}
offset
  {{ui.table.paginationOffset}}

You can set the default sort column and direction in JavaScript using the ?? operator. In our example here, it means - "if sortColumn is empty, use id column instead".

Notice how the name filter now requires quotes around the variable name:

CONCAT('%', '{{ ui.table.filters.name}}', '%')

As the query is not converted to prepared statements anymore, you need to add proper quotes around string values manually.

And don't forget to assign the action with the sorting variables to the On Sort Change trigger.

Troubleshooting

If everything is configured properly, but the action does not return the expected values, check the following:

By default, dynamic sorting doesn't work as the Convert SQL queries to prepared statements . You need to turn this setting OFF to allow dynamic sorting. But be cautious - disabling this setting can cause SQL injection!

📌
Table
Grid View
List view
implemented separately
Page-based
Cursor-based
option is enabled