Composables
useConvexPaginatedQuery
Paginate Convex queries with real-time updates.
Paginate a Convex query that returns a PaginationResult. This composable is client-only and subscribes to real-time updates. For SSR, use useConvexQuery and fetch a single page on the server.
Usage
app/components/Tasks.vue
<script setup lang="ts">
import { api } from '#convex/api'
const {
data,
pages,
isDone,
isLoading,
isLoadingMore,
loadMore,
reset,
} = useConvexPaginatedQuery(api.tasks.listPaginated, {}, { numItems: 20 })
</script>
<template>
<div v-if="isLoading">
Loading…
</div>
<ul v-else>
<li v-for="task in data" :key="task._id">
{{ task.title }}
</li>
</ul>
<button :disabled="isDone || isLoadingMore" @click="loadMore">
Load more
</button>
<button @click="reset">
Reset
</button>
</template>
Parameters
| Parameter | Type | Description |
|---|---|---|
query | FunctionReference<'query'> | The paginated Convex query to call. |
args | object | Arguments for the query (excluding paginationOpts). |
options | { numItems: number } | Number of items per page. |
Return Values
| Property | Type | Description |
|---|---|---|
data | ComputedRef<T[]> | Flattened list of all loaded pages. |
pages | ComputedRef<T[][]> | Array of pages. |
lastPage | ComputedRef<PaginationResult<T> | undefined> | Last page result. |
isDone | Ref<boolean> | True when all pages are loaded. |
isLoading | ComputedRef<boolean> | True while the first page is loading. |
isLoadingMore | Ref<boolean> | True while loading additional pages. |
loadMore | () => void | Load the next page. |
reset | () => void | Clear pages and reload from the start. |
suspense | () => Promise<T[][]> | Resolves when the first page is available. |
Components
nuxt-convex also includes renderless components for template usage:
<ConvexQuery>
<ConvexQuery :query="api.tasks.list" :args="{}">
<template #loading>Loading…</template>
<template #error="{ error }">Error: {{ error.message }}</template>
<template #empty>No tasks yet.</template>
<template #default="{ data }">
<ul>
<li v-for="task in data" :key="task._id">{{ task.title }}</li>
</ul>
</template>
</ConvexQuery>
<ConvexPaginatedQuery>
<ConvexPaginatedQuery :query="api.tasks.listPaginated" :args="{}" :options="{ numItems: 20 }">
<template #loading>Loading…</template>
<template #error="{ error, reset }">
<div>Error: {{ error.message }}</div>
<button @click="reset">Retry</button>
</template>
<template #empty>No tasks yet.</template>
<template #default="{ data, loadMore, isDone }">
<ul>
<li v-for="task in data" :key="task._id">{{ task.title }}</li>
</ul>
<button :disabled="isDone" @click="loadMore">Load more</button>
</template>
</ConvexPaginatedQuery>