Pagination
WPGraphQL uses cursor-based pagination via the Relay connection pattern. When your query includes pageInfo, WPNuxt automatically generates a composable with pagination support — including pageInfo, loadMore(), and full type safety.
Setup
Create a query in extend/queries/ that includes pageInfo alongside nodes:
query PaginatedPosts($first: Int, $after: String, $last: Int, $before: String) {
posts(first: $first, after: $after, last: $last, before: $before) {
pageInfo {
hasNextPage
hasPreviousPage
endCursor
startCursor
}
nodes {
...Post
}
}
}
Run pnpm nuxt prepare to generate the composable. usePaginatedPosts() is now available with pagination support.
Infinite Scroll
Use loadMore() to fetch the next page and append items to the list. Items accumulate automatically:
<script setup lang="ts">
const { data: posts, pageInfo, loadMore, pending } = await usePaginatedPosts({ first: 10 })
</script>
<template>
<article v-for="post in posts" :key="post.databaseId">
<h2>{{ post.title }}</h2>
</article>
<button
v-if="pageInfo?.hasNextPage"
:disabled="pending"
@click="loadMore"
>
Load more
</button>
</template>
Each call to loadMore() fetches the next page using the current endCursor and appends the results. Call refresh() to reset back to the first page.
Page-based Navigation
For previous/next page navigation, manage the cursor yourself with reactive params:
<script setup lang="ts">
const after = ref<string>()
const before = ref<string>()
const params = computed(() => {
if (before.value) {
return { last: 10, before: before.value }
}
return { first: 10, after: after.value }
})
const { data: posts, pageInfo, pending } = await usePaginatedPosts(params)
function nextPage() {
if (pageInfo.value?.hasNextPage && pageInfo.value.endCursor) {
before.value = undefined
after.value = pageInfo.value.endCursor
}
}
function previousPage() {
if (pageInfo.value?.hasPreviousPage && pageInfo.value.startCursor) {
after.value = undefined
before.value = pageInfo.value.startCursor
}
}
</script>
<template>
<article v-for="post in posts" :key="post.databaseId">
<h2>{{ post.title }}</h2>
</article>
<div>
<button v-if="pageInfo?.hasPreviousPage" @click="previousPage">
← Previous
</button>
<button v-if="pageInfo?.hasNextPage" @click="nextPage">
Next →
</button>
</div>
</template>
{ clientCache: false } as an option to ensure each page fetch hits the server.How It Works
WPNuxt detects the connection pattern (pageInfo + nodes as sibling fields) during query parsing. When detected, the generated composable uses useWPConnection instead of useWPContent, which:
- Extracts
nodesasdata(the items array) - Extracts
pageInfoseparately - Provides
loadMore()for accumulation - Handles
refresh()with accumulation reset
This is fully automatic — just add pageInfo to your query and the composable gains pagination capabilities.
Related Pages
- Custom Queries — How to create the paginated query
- Composables Reference — Full API reference for connection queries
- Fetching Data — Reactive params and other composable options