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 createInfiniteQuery function. It manages multiple pages of data and provides methods to load more pages in Svelte 5 applications.
Signature
function createInfiniteQuery < TQueryFnData , TError , TData , TQueryKey , TPageParam >(
options : Accessor < CreateInfiniteQueryOptions < TQueryFnData , TError , TData , TQueryKey , TPageParam >>,
queryClient ?: Accessor < QueryClient >,
) : CreateInfiniteQueryResult < TData , TError >
Parameters
options
Accessor<CreateInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>
required
A function (accessor) returning infinite query configuration options. Unique identifier for the query.
queryFn
(context: QueryFunctionContext<TQueryKey, TPageParam>) => Promise<TQueryFnData>
required
Function that fetches a page of data. Receives pageParam in context.
The initial page parameter for the first page.
getNextPageParam
(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.
getPreviousPageParam
(firstPage: TQueryFnData, allPages: TQueryFnData[], firstPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null
Function to determine the previous page parameter for bi-directional pagination.
Set to false to disable automatic query execution.
Time in milliseconds until cached data is considered stale.
Time in milliseconds before unused data is garbage collected.
Refetch when window regains focus.
select
(data: InfiniteData<TQueryFnData, TPageParam>) => TData
Transform or select a part of the data.
Accessor returning a custom QueryClient instance. If not provided, uses the client from context.
Returns
CreateInfiniteQueryResult<TData, TError>
Reactive infinite query state and methods. data
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
'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 lang = "ts" >
import { createInfiniteQuery } from '@tanstack/svelte-query'
const query = createInfiniteQuery (() => ({
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
},
}))
function loadMore () {
query . fetchNextPage ()
}
</ script >
{# each query . data ?. pages ?? [] as page }
{# each page . posts as post }
< div >
< h3 > { post . title } </ h3 >
< p > { post . body } </ p >
</ div >
{/ each }
{/ each }
< button
onclick = { loadMore }
disabled = { ! query . hasNextPage || query . isFetchingNextPage }
>
{# if query . isFetchingNextPage }
Loading more...
{: else if query . hasNextPage }
Load More
{: else }
No more posts
{/ if }
</ button >
< script lang = "ts" >
import { createInfiniteQuery } from '@tanstack/svelte-query'
const query = createInfiniteQuery (() => ({
queryKey: [ 'posts' ],
queryFn : async ({ pageParam }) => {
const res = await fetch ( `/api/posts?cursor= ${ pageParam } ` )
return res . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
}))
</ script >
< script lang = "ts" >
import { createInfiniteQuery } from '@tanstack/svelte-query'
const query = createInfiniteQuery (() => ({
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 >
< button
onclick = { () => query . fetchPreviousPage () }
disabled = { ! query . hasPreviousPage || query . isFetchingPreviousPage }
>
Load Previous
</ button >
<!-- Posts display -->
< button
onclick = { () => query . fetchNextPage () }
disabled = { ! query . hasNextPage || query . isFetchingNextPage }
>
Load Next
</ button >
With TypeScript
< script lang = "ts" >
import { createInfiniteQuery } from '@tanstack/svelte-query'
interface Post {
id : number
title : string
body : string
}
interface PostsPage {
posts : Post []
nextCursor ?: number
hasMore : boolean
}
const query = createInfiniteQuery (() => ({
queryKey: [ 'posts' ],
queryFn : async ({ pageParam }) : Promise < PostsPage > => {
const res = await fetch ( `/api/posts?cursor= ${ pageParam } ` )
return res . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
}))
// query.data.pages is typed as PostsPage[]
</ script >
Reactive Query Parameters
< script lang = "ts" >
import { createInfiniteQuery } from '@tanstack/svelte-query'
let filter = $ state ( 'all' )
const query = createInfiniteQuery (() => ({
queryKey: [ 'posts' , filter ],
queryFn : async ({ pageParam }) => {
const res = await fetch (
`/api/posts?filter= ${ filter } &cursor= ${ pageParam } `
)
return res . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
}))
</ script >
< select bind : value = { filter } >
< option value = "all" > All </ option >
< option value = "active" > Active </ option >
< option value = "completed" > Completed </ option >
</ select >
< script lang = "ts" >
import { createInfiniteQuery } from '@tanstack/svelte-query'
import { onMount } from 'svelte'
let loadMoreRef : HTMLDivElement
const query = createInfiniteQuery (() => ({
queryKey: [ 'posts' ],
queryFn: fetchPosts ,
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
}))
onMount (() => {
const observer = new IntersectionObserver (
([ entry ]) => {
if (
entry . isIntersecting &&
query . hasNextPage &&
! query . isFetchingNextPage
) {
query . fetchNextPage ()
}
},
{ threshold: 1.0 }
)
if ( loadMoreRef ) {
observer . observe ( loadMoreRef )
}
return () => observer . disconnect ()
})
</ script >
< div >
{# each query . data ?. pages ?? [] as page }
{# each page . posts as post }
< div > { post . title } </ div >
{/ each }
{/ each }
{# if query . hasNextPage }
< div bind : this = { loadMoreRef } >
{# if query . isFetchingNextPage }
Loading...
{/ if }
</ div >
{/ if }
</ div >
Refetch All Pages
< script lang = "ts" >
import { createInfiniteQuery } from '@tanstack/svelte-query'
const query = createInfiniteQuery (() => ({
queryKey: [ 'posts' ],
queryFn: fetchPosts ,
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
}))
function refreshAll () {
query . refetch () // Refetches all loaded pages
}
</ script >
< button onclick = { refreshAll } > Refresh All </ button >
With Loading States
< script lang = "ts" >
import { createInfiniteQuery } from '@tanstack/svelte-query'
const query = createInfiniteQuery (() => ({
queryKey: [ 'posts' ],
queryFn: fetchPosts ,
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
}))
</ script >
{# if query . isLoading }
< div > Loading first page... </ div >
{: else if query . isError }
< div > Error: { query . error ?. message } </ div >
{: else if query . isSuccess }
{# each query . data . pages as page }
{# each page . posts as post }
< div > { post . title } </ div >
{/ each }
{/ each }
{# if query . hasNextPage }
< button
onclick = { () => query . fetchNextPage () }
disabled = { query . isFetchingNextPage }
>
{ query . isFetchingNextPage ? 'Loading...' : 'Load More' }
</ button >
{/ if }
{/ if }
< script lang = "ts" >
import { createInfiniteQuery } from '@tanstack/svelte-query'
const query = createInfiniteQuery (() => ({
queryKey: [ 'posts' ],
queryFn : async ({ pageParam }) => {
const res = await fetch ( `/api/posts?page= ${ pageParam } &limit=10` )
return res . json ()
},
initialPageParam: 1 ,
getNextPageParam : ( lastPage , allPages , lastPageParam ) => {
return lastPage . hasMore ? lastPageParam + 1 : undefined
},
getPreviousPageParam : ( firstPage , allPages , firstPageParam ) => {
return firstPageParam > 1 ? firstPageParam - 1 : undefined
},
}))
</ script >
< script lang = "ts" >
import { createInfiniteQuery } from '@tanstack/svelte-query'
let searchTerm = $ state ( '' )
let debouncedSearch = $ state ( '' )
// Debounce search
$ effect (() => {
const timeout = setTimeout (() => {
debouncedSearch = searchTerm
}, 300 )
return () => clearTimeout ( timeout )
})
const query = createInfiniteQuery (() => ({
queryKey: [ 'posts' , 'search' , debouncedSearch ],
queryFn : async ({ pageParam }) => {
const res = await fetch (
`/api/posts?search= ${ debouncedSearch } &cursor= ${ pageParam } `
)
return res . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
enabled: debouncedSearch . length > 0 ,
}))
</ script >
< input
type = "text"
bind : value = { searchTerm }
placeholder = "Search posts..."
/>
{# if query . data }
{# each query . data . pages as page }
{# each page . posts as post }
< div > { post . title } </ div >
{/ each }
{/ each }
{/ if }
Notes
Svelte Query uses Svelte 5’s runes mode. The options parameter must be an accessor (function) to track reactive dependencies.
initialPageParam is required in v5. Make sure to provide it when creating infinite queries.
When using refetch(), all pages will be refetched. For better UX, consider using invalidateQueries to only refetch when needed.