8.0k New

Pagination

Pagination with page navigation, next and previous links.

Docs API Reference

Epicenter

Local-first, open source apps

Special Sponsor
<script lang="ts">
  import * as Pagination from "$lib/components/ui/pagination/index.js";
</script>
 
<Pagination.Root count={30} perPage={10} page={2}>
  {#snippet children({ pages, currentPage })}
    <Pagination.Content>
      <Pagination.Item>
        <Pagination.Previous />
      </Pagination.Item>
      {#each pages as page (page.key)}
        {#if page.type === "ellipsis"}
          <Pagination.Item>
            <Pagination.Ellipsis />
          </Pagination.Item>
        {:else}
          <Pagination.Item>
            <Pagination.Link {page} isActive={currentPage === page.value}>
              {page.value}
            </Pagination.Link>
          </Pagination.Item>
        {/if}
      {/each}
      <Pagination.Item>
        <Pagination.Ellipsis />
      </Pagination.Item>
      <Pagination.Item>
        <Pagination.Next />
      </Pagination.Item>
    </Pagination.Content>
  {/snippet}
</Pagination.Root>

Installation

pnpm dlx shadcn-svelte@latest add pagination

Usage

<script lang="ts">
  import * as Pagination from "$lib/components/ui/pagination/index.js";
</script>
<Pagination.Root count={100} perPage={10}>
  {#snippet children({ pages, currentPage })}
    <Pagination.Content>
      <Pagination.Item>
        <Pagination.Previous />
      </Pagination.Item>
      {#each pages as page (page.key)}
        {#if page.type === "ellipsis"}
          <Pagination.Item>
            <Pagination.Ellipsis />
          </Pagination.Item>
        {:else}
          <Pagination.Item>
            <Pagination.Link {page} isActive={currentPage === page.value}>
              {page.value}
            </Pagination.Link>
          </Pagination.Item>
        {/if}
      {/each}
      <Pagination.Item>
        <Pagination.Next />
      </Pagination.Item>
    </Pagination.Content>
  {/snippet}
</Pagination.Root>

Simple

A simple pagination with only page numbers.

<script lang="ts">
  import * as Pagination from "$lib/components/ui/pagination/index.js";
</script>
 
<Pagination.Root count={50} perPage={10} page={2}>
  {#snippet children({ pages, currentPage })}
    <Pagination.Content>
      {#each pages as page (page.key)}
        {#if page.type === "page"}
          <Pagination.Item>
            <Pagination.Link {page} isActive={currentPage === page.value}>
              {page.value}
            </Pagination.Link>
          </Pagination.Item>
        {/if}
      {/each}
    </Pagination.Content>
  {/snippet}
</Pagination.Root>

Icons Only

Use just the previous and next buttons without page numbers. This is useful for data tables with a rows per page selector.

<script lang="ts">
  import * as Field from "$lib/components/ui/field/index.js";
  import * as Pagination from "$lib/components/ui/pagination/index.js";
  import * as Select from "$lib/components/ui/select/index.js";
 
  const rowsPerPage = ["10", "25", "50", "100"];
 
  let perPage = $state("25");
</script>
 
<div class="flex items-center justify-between gap-4">
  <Field.Field orientation="horizontal" class="w-fit">
    <Field.Label for="select-rows-per-page">Rows per page</Field.Label>
    <Select.Root type="single" bind:value={perPage}>
      <Select.Trigger class="w-20" id="select-rows-per-page">
        <Select.Value />
      </Select.Trigger>
      <Select.Content align="start">
        <Select.Group>
          {#each rowsPerPage as rows (rows)}
            <Select.Item value={rows} label={rows}>{rows}</Select.Item>
          {/each}
        </Select.Group>
      </Select.Content>
    </Select.Root>
  </Field.Field>
  <Pagination.Root count={100} perPage={Number(perPage)} class="mx-0 w-auto">
    <Pagination.Content>
      <Pagination.Item>
        <Pagination.Previous />
      </Pagination.Item>
      <Pagination.Item>
        <Pagination.Next />
      </Pagination.Item>
    </Pagination.Content>
  </Pagination.Root>
</div>