Skip to content

Pagination

npm package: import it from 'flootlets'
bun add flootlets
Or copy it in with the shadcn CLI: import it from '@/components/ui/…'
npx shadcn@latest add https://dyeoh.github.io/flootlets/r/pagination.json

Both need Tailwind CSS v4; see Installation for the setup.

import { createSignal } from 'solid-js';
export default function PaginationExample() {
const [page, setPage] = createSignal(5);
return (
<Stack gap={4} align="center" class="w-full">
{/* Links, as on a server-rendered product listing. */}
<Pagination page={5} totalPages={12} href={(p) => `?page=${p}`} />
{/* The gnerkulfloot API gives has_more instead of a total. */}
<Pagination page={2} hasMore href={(p) => `?page=${p}`} />
{/* Buttons, paging in place. */}
<Pagination page={page()} totalPages={8} onPageChange={setPage} />
</Stack>
);
}

Give it href and every page is a link (?page=3). Links work before JavaScript loads, search engines can follow them, and screen readers announce them as navigation. Give it onPageChange instead and they’re buttons, for lists that page in place.

With totalPages it shows numbers: the current page ±1, the first and last, and ellipses between. The gnerkulfloot API returns has_more rather than a total count, so with hasMore and no totalPages it shows Previous, “Page N” and Next.

The current page is marked aria-current="page" and isn’t a link, since there’s nowhere to go. Previous and Next carry rel="prev" / rel="next".

Prop Type
page number Current page, from 1
totalPages number If known
hasMore boolean Without totalPages: is there a next page
href (page: number) => string Pages become links
onPageChange (page: number) => void Pages become buttons
labels { nav, previous, next, page: (n) => … } Translations

flootlets 0.2.3 · Changelog