Skip to main content

Migrate Pagination from Polaris React

Polaris web components don't provide a standalone Pagination component. Use built-in s-table pagination for table results. For other content, compose visible previous and next navigation and keep it backed by the same URL and backend query state as the displayed results.


Anchor to Migrate non-table paginationMigrate non-table pagination

Use real URLs when each page has a stable destination. This preserves direct loads, modified clicks, copied links, and browser history.

Migrating article pagination

function ArticlePagination({previousUrl, nextUrl, label}) {
return (
<nav aria-label="Article pagination">
<s-stack
direction="inline"
gap="small"
alignItems="center"
justifyContent="center"
>
<s-button
icon="chevron-left"
href={previousUrl}
disabled={!previousUrl}
>
Previous
</s-button>
<s-box paddingInline="small">
<s-text>{label}</s-text>
</s-box>
<s-button
icon="chevron-right"
href={nextUrl}
disabled={!nextUrl}
>
Next
</s-button>
</s-stack>
</nav>
);
}
import {Pagination} from '@shopify/polaris';

export function ArticlePagination({previousUrl, nextUrl, label}) {
return (
<Pagination
accessibilityLabel="Article pagination"
previousURL={previousUrl}
nextURL={nextUrl}
hasPrevious={Boolean(previousUrl)}
hasNext={Boolean(nextUrl)}
label={label}
/>
);
}

Preview


Anchor to Use s-table pagination for table dataUse s-table pagination for table data

Set paginate on s-table, derive hasPreviousPage and hasNextPage from backend page information, and handle onPreviousPage and onNextPage. Keep loading, sort, filters, cursor, and visible rows in one data-view model.

Reset the cursor whenever search, filters, or sorting changes. A cursor from an earlier query doesn't identify a page in the new result set. See the DataTable migration for a complete example.


Anchor to Map pagination behaviorMap pagination behavior

Polaris ReactPolaris web componentsMigration notes
previousURL and nextURLhref on previous and next controlsKeep real URLs when pages are addressable.
onPrevious and onNextonClick or table page eventsUse callbacks for app-owned cursor requests that don't have a link destination.
hasPrevious and hasNextdisabled for composed controls, or hasPreviousPage and hasNextPage on s-tableDerive availability from the current backend response.
labelVisible s-text between controlsKeep useful context such as Page 2 of 5 when the total is reliable.
accessibilityLabel and button labelsVisible labels plus accessibilityLabel when extra context is neededDon't rely on arrow icons alone.
type="table"paginate on s-tableKeep the controls with the table they update.
nextTooltip and previousTooltipVisible button textA tooltip isn't a substitute for the control's accessible name.
nextKeys and previousKeysRemove in most appsDon't register global shortcuts that conflict with browser or admin behavior.

Anchor to Keep query and navigation state togetherKeep query and navigation state together

For cursor pagination, store the cursor and direction in URL search parameters when the result page should restore after reload or browser navigation. Keep the active search, filters, and sort values in that same URL. For numbered pages, validate requested page bounds on the server.

While a page request is pending, preserve the current results or render an intentional loading state, and block duplicate page requests. After results load, move focus only when needed to keep the merchant oriented; don't force focus on every background refresh.


  • Navigate to first, middle, and last pages and verify control availability.
  • Reload, use back and forward navigation, and open a page URL directly.
  • Change search, filters, or sort from a later page and verify pagination resets.
  • Test slow, failed, duplicate, and out-of-order page requests.
  • Verify table and non-table controls have visible, specific names and keyboard focus.
  • Confirm empty or deleted result pages recover to a valid location.

Anchor to Remove Polaris ReactRemove Polaris React

After every call site is migrated, remove Pagination, keyboard-shortcut helpers used only by it, and duplicate page state. Remove @shopify/polaris only after no other route in scope imports it.



Was this page helpful?