Documentation Index Fetch the complete documentation index at: https://mintlify.com/TanStack/query/llms.txt
Use this file to discover all available pages before exploring further.
Fetch paginated or infinite scrolling data with the useInfiniteQuery composable. It manages multiple pages of data and provides methods to load more pages.
Signature
function useInfiniteQuery < TQueryFnData , TError , TData , TQueryKey , TPageParam >(
options : UseInfiniteQueryOptions < TQueryFnData , TError , TData , TQueryKey , TPageParam >,
queryClient ?: QueryClient ,
) : UseInfiniteQueryReturnType < TData , TError >
Parameters
options
UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
required
Configuration options for the infinite query. Can be a reactive ref or getter function. queryKey
MaybeRefDeep<QueryKey>
required
Unique identifier for the query. Can be a ref or contain refs.
queryFn
MaybeRefDeep<(context: QueryFunctionContext<TQueryKey, TPageParam>) => Promise<TQueryFnData>>
required
Function that fetches a page of data. Receives pageParam in context. Can be a ref.
The initial page parameter for the first page.
getNextPageParam
MaybeRefDeep<(lastPage: TQueryFnData, allPages: TQueryFnData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null>
required
Function to determine the next page parameter. Return undefined or null when there are no more pages. Can be a ref.
getPreviousPageParam
MaybeRefDeep<(firstPage: TQueryFnData, allPages: TQueryFnData[], firstPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null>
Function to determine the previous page parameter for bi-directional pagination. Can be a ref.
enabled
MaybeRefOrGetter<boolean>
Set to false to disable automatic query execution. Supports refs and getters.
Time in milliseconds until cached data is considered stale. Can be a ref.
Time in milliseconds before unused data is garbage collected. Can be a ref.
Refetch when window regains focus. Can be a ref.
select
MaybeRefDeep<(data: InfiniteData<TQueryFnData, TPageParam>) => TData>
Transform or select a part of the data. Can be a ref.
Return data in a shallow ref (improves performance if data doesn’t need deep reactivity).
Custom QueryClient instance. If not provided, uses the client from context.
Returns
UseInfiniteQueryReturnType<TData, TError>
Reactive refs containing infinite query state and methods. data
Ref<InfiniteData<TData, TPageParam> | undefined>
Object containing all pages of data with pages and pageParams arrays.
The error object if the query failed.
true when fetching the first page for the first time.
true whenever the query is fetching (including additional pages).
true when fetching the next page.
true when fetching the previous page.
true if there is a next page to fetch.
true if there is a previous page to fetch.
fetchNextPage
(options?: FetchNextPageOptions) => Promise<InfiniteQueryObserverResult>
Fetch the next page of data.
fetchPreviousPage
(options?: FetchPreviousPageOptions) => Promise<InfiniteQueryObserverResult>
Fetch the previous page of data.
true when the query has successfully fetched data.
true when the query encountered an error.
status
Ref<'pending' | 'error' | 'success'>
The current status of the query.
refetch
() => Promise<InfiniteQueryObserverResult>
Manually trigger a refetch of all pages.
Type Parameters
TQueryFnData - Type of data returned by each page
TError - Type of error (defaults to DefaultError)
TData - Type of final data (defaults to InfiniteData<TQueryFnData>)
TQueryKey - Type of the query key (defaults to QueryKey)
TPageParam - Type of page parameter (defaults to unknown)
Examples
< script setup >
import { useInfiniteQuery } from '@tanstack/vue-query'
const {
data ,
fetchNextPage ,
hasNextPage ,
isFetchingNextPage ,
} = useInfiniteQuery ({
queryKey: [ 'posts' ],
queryFn : async ({ pageParam }) => {
const res = await fetch ( `/api/posts?page= ${ pageParam } ` )
return res . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage , allPages ) => {
return lastPage . hasMore ? allPages . length : undefined
},
})
</ script >
< template >
< div >
< div v-for = " page in data ?. pages " : key = " page . id " >
< div v-for = " post in page . posts " : key = " post . id " >
< h3 > {{ post . title }} </ h3 >
< p > {{ post . body }} </ p >
</ div >
</ div >
< button
@ click = " fetchNextPage () "
: disabled = " ! hasNextPage || isFetchingNextPage "
>
< span v-if = " isFetchingNextPage " > Loading more... </ span >
< span v-else-if = " hasNextPage " > Load More </ span >
< span v-else > No more posts </ span >
</ button >
</ div >
</ template >
< script setup >
import { useInfiniteQuery } from '@tanstack/vue-query'
const { data , fetchNextPage , hasNextPage } = useInfiniteQuery ({
queryKey: [ 'posts' ],
queryFn : async ({ pageParam }) => {
const res = await fetch ( `/api/posts?cursor= ${ pageParam } ` )
return res . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
})
</ script >
< script setup >
import { useInfiniteQuery } from '@tanstack/vue-query'
const {
data ,
fetchNextPage ,
fetchPreviousPage ,
hasNextPage ,
hasPreviousPage ,
} = useInfiniteQuery ({
queryKey: [ 'posts' ],
queryFn : async ({ pageParam }) => {
const res = await fetch ( `/api/posts?cursor= ${ pageParam } ` )
return res . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
getPreviousPageParam : ( firstPage ) => firstPage . prevCursor ,
})
</ script >
< template >
< div >
< button @ click = " fetchPreviousPage () " : disabled = " ! hasPreviousPage " >
Load Previous
</ button >
<!-- Posts display -->
< button @ click = " fetchNextPage () " : disabled = " ! hasNextPage " >
Load Next
</ button >
</ div >
</ template >
With TypeScript
< script setup lang = "ts" >
import { useInfiniteQuery } from '@tanstack/vue-query'
interface Post {
id : number
title : string
body : string
}
interface PostsPage {
posts : Post []
nextCursor ?: number
hasMore : boolean
}
const { data } = useInfiniteQuery ({
queryKey: [ 'posts' ],
queryFn : async ({ pageParam }) : Promise < PostsPage > => {
const res = await fetch ( `/api/posts?cursor= ${ pageParam } ` )
return res . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
})
// data.pages is typed as PostsPage[]
</ script >
Reactive Page Parameters
< script setup >
import { ref } from 'vue'
import { useInfiniteQuery } from '@tanstack/vue-query'
const filter = ref ( 'all' )
const { data , fetchNextPage } = useInfiniteQuery ({
queryKey: [ 'posts' , filter ], // Refetches when filter changes
queryFn : async ({ pageParam }) => {
const res = await fetch (
`/api/posts?filter= ${ filter . value } &cursor= ${ pageParam } `
)
return res . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
})
</ script >
< template >
< select v-model = " filter " >
< option value = "all" > All </ option >
< option value = "active" > Active </ option >
< option value = "completed" > Completed </ option >
</ select >
</ template >
< script setup >
import { ref , watch } from 'vue'
import { useInfiniteQuery } from '@tanstack/vue-query'
const loadMoreRef = ref ( null )
const { data , fetchNextPage , hasNextPage , isFetchingNextPage } = useInfiniteQuery ({
queryKey: [ 'posts' ],
queryFn: fetchPosts ,
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
})
// Auto-load more when element is visible
watch ( loadMoreRef , ( el ) => {
if ( ! el ) return
const observer = new IntersectionObserver (
([ entry ]) => {
if ( entry . isIntersecting && hasNextPage . value && ! isFetchingNextPage . value ) {
fetchNextPage ()
}
},
{ threshold: 1.0 }
)
observer . observe ( el )
})
</ script >
< template >
< div >
< div v-for = " page in data ?. pages " : key = " page . id " >
< div v-for = " post in page . posts " : key = " post . id " >
{{ post . title }}
</ div >
</ div >
< div ref = "loadMoreRef" v-if = " hasNextPage " >
< span v-if = " isFetchingNextPage " > Loading... </ span >
</ div >
</ div >
</ template >
Refetch All Pages
< script setup >
import { useInfiniteQuery } from '@tanstack/vue-query'
const { data , refetch } = useInfiniteQuery ({
queryKey: [ 'posts' ],
queryFn: fetchPosts ,
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
})
const refreshAll = () => {
// Refetches all loaded pages
refetch ()
}
</ script >