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
Polaris web components
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>
);
}Polaris React
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 React | Polaris web components | Migration notes |
|---|---|---|
previousURL and nextURL | href on previous and next controls | Keep real URLs when pages are addressable. |
onPrevious and onNext | onClick or table page events | Use callbacks for app-owned cursor requests that don't have a link destination. |
hasPrevious and hasNext | disabled for composed controls, or hasPreviousPage and hasNextPage on s-table | Derive availability from the current backend response. |
label | Visible s-text between controls | Keep useful context such as Page 2 of 5 when the total is reliable. |
accessibilityLabel and button labels | Visible labels plus accessibilityLabel when extra context is needed | Don't rely on arrow icons alone. |
type="table" | paginate on s-table | Keep the controls with the table they update. |
nextTooltip and previousTooltip | Visible button text | A tooltip isn't a substitute for the control's accessible name. |
nextKeys and previousKeys | Remove in most apps | Don't register global shortcuts that conflict with browser or admin behavior. |
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.
Anchor to Test the migrationTest the migration
- 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.