Pagination
URL-driven page state via searchParams. The loader slices the dataset by ?page=N; links navigate the browser, no client JS. Refresh, share, and back/forward all work because the page number lives in the URL.
Tip
Every ?page=N URL is bookmarkable and crawlable — unlike client-side state. Combine server pagination with infinite scroll by pre-rendering page 1 then fetching subsequent pages via the same URL.
Rows 21–30 of 47
- #21 · Item 21
- #22 · Item 22
- #23 · Item 23
- #24 · Item 24
- #25 · Item 25
- #26 · Item 26
- #27 · Item 27
- #28 · Item 28
- #29 · Item 29
- #30 · Item 30
// Page reads ?page from searchParams; loader returns the slice +
// pagination metadata. Links carry ?page=N — no client JS, no
// state. Browser back/forward Just Works.
export async function loader({ request }) {
const url = new URL(request.url);
const page = Math.max(1, parseInt(url.searchParams.get("page") ?? "1", 10));
const start = (page - 1) * PAGE_SIZE;
return {
rows: items.slice(start, start + PAGE_SIZE),
page,
totalPages: Math.ceil(items.length / PAGE_SIZE),
};
}
// Render: <a href={"?page=" + (page - 1)}>← prev</a>