Skip to main content
Initial query data allows you to provide pre-populated data to a query before it fetches. This is useful when you have data from server-side rendering, local storage, or other sources that can be used immediately while fresh data is being fetched in the background.

Basic Usage

Provide initial data using the initialData option:
import { useQuery } from '@tanstack/react-query'

function Todo({ id }) {
  const { data } = useQuery({
    queryKey: ['todo', id],
    queryFn: () => fetchTodo(id),
    initialData: { id, title: 'Loading...', completed: false }
  })

  return <div>{data.title}</div>
}
When initialData is provided, the query will immediately be in a success state with the initial data, but it will still fetch in the background if the data is stale.

Initial Data Function

You can also provide a function that returns initial data. This is useful for deriving initial data from other queries:
import { useQuery, useQueryClient } from '@tanstack/react-query'

function TodoDetail({ id }) {
  const queryClient = useQueryClient()

  const { data } = useQuery({
    queryKey: ['todo', id],
    queryFn: () => fetchTodo(id),
    initialData: () => {
      // Use a todo from the 'todos' query as initial data
      return queryClient
        .getQueryData(['todos'])
        ?.find(todo => todo.id === id)
    }
  })

  return <div>{data?.title}</div>
}

Initial Data Updated At

Control when initial data is considered stale using initialDataUpdatedAt:
import { useQuery } from '@tanstack/react-query'

function Todo({ id, cachedTodo, cachedAt }) {
  const { data, isFetching } = useQuery({
    queryKey: ['todo', id],
    queryFn: () => fetchTodo(id),
    initialData: cachedTodo,
    initialDataUpdatedAt: cachedAt,
    staleTime: 5000 // 5 seconds
  })

  return (
    <div>
      <div>{data.title}</div>
      {isFetching && <span>Updating...</span>}
    </div>
  )
}
1

Set initialData

Provide the cached data to immediately render content
2

Set initialDataUpdatedAt

Specify when the data was cached (timestamp in milliseconds)
3

Configure staleTime

If the current time minus initialDataUpdatedAt is less than staleTime, the query won’t refetch

Type Safety

The initialData must match the query’s data type:
interface Todo {
  id: number
  title: string
  completed: boolean
}

function useTodo(id: number) {
  return useQuery({
    queryKey: ['todo', id],
    queryFn: async (): Promise<Todo> => {
      const res = await fetch(`/api/todos/${id}`)
      return res.json()
    },
    // ✅ Correct: matches Todo type
    initialData: { id, title: '', completed: false },
    // ❌ Error: missing required properties
    // initialData: { id }
  })
}

Behavior with Fetching State

Even with initialData, queries will still fetch if the data is stale:
function Todo() {
  const { data, isFetching } = useQuery({
    queryKey: ['todo'],
    queryFn: async () => {
      await sleep(1000)
      return 'serverData'
    },
    initialData: 'initialData'
  })

  // First render:
  // data: 'initialData'
  // isFetching: true
  
  // After fetch completes:
  // data: 'serverData'
  // isFetching: false

  return <div>{data}</div>
}
The query state will be success immediately, but isFetching will be true while the background fetch is in progress.

Working with Falsy Values

Falsy values like 0, false, or '' are valid initial data:
function Counter() {
  const { data } = useQuery({
    queryKey: ['count'],
    queryFn: () => fetchCount(),
    initialData: 0  // ✅ Valid initial data
  })

  return <div>Count: {data}</div>
}

When to Use Initial Data

Use initialData when:
  • You have data from server-side rendering (SSR)
  • You’re deriving data from another query in the cache
  • You have cached data from local storage
  • You want to provide a default value while fetching
For loading states, consider using placeholderData instead.

Differences from Placeholder Data

FeatureinitialDataplaceholderData
Persisted to cache✅ Yes❌ No
Marks query as successful✅ Yes❌ No
Triggers onSuccess✅ Yes❌ No
Can be invalidated✅ Yes❌ No
Use casePre-populate with real dataShow loading state content

See Also

Build docs developers (and LLMs) love