Initial and Placeholder Data

Purpose and Scope

Initial data and placeholder data both solve the same user-facing problem: a query can render useful data before its query function has completed. They differ in where that early data lives and what it means for cache correctness. Initial data is real seed data for the query cache. Placeholder data is a temporary render strategy for an observer that should look successful while the real fetch is still happening. Use this page when deciding whether a value should become part of TanStack Query’s cached server state or should only smooth a loading transition.

Sources: docs/framework/react/guides/initial-query-data.md, docs/framework/react/guides/placeholder-query-data.md

The React guides frame both options as declarative alternatives to imperative cache preparation, but they intentionally recommend different kinds of input. The initial query data guide says there are declarative and imperative ways to supply data before a query needs it, including initialData, queryClient.prefetchQuery, and queryClient.setQueryData. It also warns that initial data is persisted to the cache, so incomplete, fake, or partial values should not be provided as initial data. The placeholder guide uses the opposite framing: partial or fake data is acceptable because it is not persisted to the cache.

Sources: docs/framework/react/guides/initial-query-data.md, docs/framework/react/guides/placeholder-query-data.md

Relevant Source Files

  • docs/framework/react/guides/initial-query-data.md — Defines the React-facing initialData workflow, the cache persistence warning, freshness behavior, staleTime, initialDataUpdatedAt, lazy initial data functions, and examples that derive initial data from another query.
  • docs/framework/react/guides/placeholder-query-data.md — Defines the React-facing placeholderData workflow, the non-persistence guarantee, isPlaceholderData, value and function forms, memoization guidance, and cache-derived placeholder examples.
  • docs/framework/angular/guides/initial-query-data.md — Mirrors the initial data guide for Angular with injectQuery, Angular initialization wording, QueryClient cache lookups, and timestamp examples.
  • docs/framework/angular/guides/placeholder-query-data.md — Mirrors the placeholder data guide for Angular with injectQuery, component examples, previous-query placeholders, and preview data pulled from QueryClient.
  • packages/react-query/src/tests/useQuery.test.tsx — Provides the React adapter’s test coverage location for useQuery option and result behavior, which is the runtime surface exercised by the React guide examples.

System-to-Code Mapping

In the public API, both features are options passed to a query observer through framework-native query APIs. In React, the examples use useQuery with a queryKey, a queryFn, and either initialData or placeholderData. In Angular, the same conceptual object is returned from a function passed to injectQuery. This adapter-level difference matters for syntax, not semantics: the query key still identifies the cache entry, the query function still fetches authoritative data, and the option decides what data is available before that authoritative fetch resolves.

Sources: docs/framework/react/guides/initial-query-data.md, docs/framework/angular/guides/initial-query-data.md, docs/framework/react/guides/placeholder-query-data.md, docs/framework/angular/guides/placeholder-query-data.md

initialData maps to cache seeding. If the query cache does not already contain data for the key, TanStack Query can populate it with the supplied value and skip the initial loading state. Because the value becomes cached data, downstream observers of the same query key can treat it as the query’s current data. That is powerful when the application truly already has the full entity or list. It is risky when the value is a preview, skeleton, or subset, because other consumers may read that partial value as canonical server state.

Sources: docs/framework/react/guides/initial-query-data.md, docs/framework/angular/guides/initial-query-data.md

placeholderData maps to observer presentation rather than cache mutation. The placeholder guide says a query using placeholder data is not in a pending state; it starts in a success state because there is data to display. The distinguishing result flag is isPlaceholderData, which tells the UI that the displayed value is temporary. This makes placeholder data a good fit for layout continuity, previews from a list view, page transitions, and avoiding a spinner while the real query for a new key is underway.

Sources: docs/framework/react/guides/placeholder-query-data.md, docs/framework/angular/guides/placeholder-query-data.md

Choosing Between Initial Data and Placeholder Data

Choose initial data when the value is complete enough to be stored as the current result for the query key. Common examples include data embedded in the page, data already fetched by a parent route, or an item selected from a cached list when that item contains all fields needed by the detail query. The guide also shows more precise cache-derived initial data by pairing initialData with initialDataUpdatedAt, using another query’s dataUpdatedAt timestamp. That allows TanStack Query to decide whether the seed data is fresh enough or should refetch immediately.

Sources: docs/framework/react/guides/initial-query-data.md, docs/framework/angular/guides/initial-query-data.md

Choose placeholder data when the value is intentionally incomplete or synthetic. A blog post detail query may display title and snippet data from a cached blog post list while fetching the full body. A todos screen may show generated fake rows to hold layout shape. A paginated or parameterized query may keep displaying the previous successful result when the key changes, using a placeholderData function that receives the previous data and previous query. In all of those cases, the UI benefits from continuity, but the cache should wait for the real fetch.

Sources: docs/framework/react/guides/placeholder-query-data.md, docs/framework/angular/guides/placeholder-query-data.md

Execution Flow

The initial data flow starts when an observer is created for a key that has no cached data. The option may be a direct value or a function. If initial data is available, the query can render data immediately. By default, the React guide says initial data is treated as freshly fetched. With the default stale time of zero, however, it also immediately refetches when mounted. If a positive staleTime is provided, the seed remains fresh for that duration, as if the query function had just returned it.

Sources: docs/framework/react/guides/initial-query-data.md

initialDataUpdatedAt refines that freshness decision. Instead of pretending the seed was produced at observer creation time, the caller can provide a JavaScript millisecond timestamp describing when the seed was last updated. The guide calls out that Unix timestamps must be converted by multiplying by one thousand. With a stale time of one minute, data updated ten seconds ago can avoid an immediate refetch, while data updated ten minutes ago can refetch as stale. This preserves the meaning of stale time as a freshness requirement rather than a seed-data delay.

Sources: docs/framework/react/guides/initial-query-data.md, docs/framework/angular/guides/initial-query-data.md

The placeholder flow starts similarly at observer creation, but the supplied value is not written as cached query data. The observer can still report success so the component renders normally, and isPlaceholderData remains available to gate controls, badges, or transitions. When the query function resolves, the authoritative result replaces the placeholder presentation. Because placeholder data can be a function, it can also implement key-transition behavior by returning the previous successful result for a new query key while the new request is in flight.

Sources: docs/framework/react/guides/placeholder-query-data.md, docs/framework/angular/guides/placeholder-query-data.md

API Components and Examples

The React API shape is identical except for the selected option. A minimal initial data query persists initialTodos for the todos key if the cache is empty:

const result = useQuery({
  queryKey: ['todos'],
  queryFn: () => fetch('/todos'),
  initialData: initialTodos,
})

The freshness-aware form adds staleTime and initialDataUpdatedAt. This is the right shape when the seed came from another source that records its update time:

const result = useQuery({
  queryKey: ['todos'],
  queryFn: () => fetch('/todos'),
  initialData: initialTodos,
  staleTime: 60 * 1000,
  initialDataUpdatedAt: initialTodosUpdatedTimestamp,
})

Placeholder data has the same query shell, but its option is expressly temporary. The direct value form is useful when the placeholder is cheap and stable, while expensive generation should be memoized so it does not run on every render. The function form is more dynamic: it receives previous successful query data and query metadata, enabling transition-friendly screens. The cache-derived placeholder example uses useQueryClient and getQueryData to find a preview item from a list query, then uses it only until the detail query finishes.

Sources: docs/framework/react/guides/placeholder-query-data.md

const result = useQuery({
  queryKey: ['todos', id],
  queryFn: () => fetch(`/todos/${id}`),
  placeholderData: (previousData, previousQuery) => previousData,
})

Angular uses the same option names but wraps them in injectQuery. The Angular initial-data guide shows initialData as a value, as a function such as getExpensiveTodos, and as a cache lookup from QueryClient. It also shows initialDataUpdatedAt as a function that reads getQueryState(['todos'])?.dataUpdatedAt. The Angular placeholder guide mirrors React’s value, previous-data function, and preview-from-cache patterns inside component classes. When translating examples, preserve the cache semantics and change only the adapter syntax.

Sources: docs/framework/angular/guides/initial-query-data.md, docs/framework/angular/guides/placeholder-query-data.md

Comparison Reference

Decision pointinitialDataplaceholderData
Cache effectPersists the supplied value to the query cache when the cache is emptyDoes not persist the supplied value to the cache
Best inputComplete, trustworthy data for the query keyPartial, fake, preview, or previous data used for UI continuity
Initial stateSkips the initial loading state because data existsStarts in success because display data exists
Freshness controlsWorks with staleTime and initialDataUpdatedAtReplaced by real fetched data; use isPlaceholderData to distinguish it
Common sourceEmbedded data, prefetched data, another complete cached queryList previews, generated placeholders, previous query results during key transitions

Testing Signals

The React examples ultimately exercise the useQuery surface, and the requested source set includes the React adapter test file for that hook. Treat the guides as the reader-facing contract and the hook tests as the implementation safety net for option behavior and result state. When changing React query observer behavior, update guide examples only if the public semantics change, and check the useQuery tests for matching coverage. For Angular, keep the adapter examples semantically aligned with React while respecting injectQuery, signals, component initialization, and injected QueryClient usage.

Sources: packages/react-query/src/tests/useQuery.test.tsx, docs/framework/react/guides/initial-query-data.md, docs/framework/angular/guides/initial-query-data.md

Next Steps

If you are seeding complete data before navigation, continue with the prefetching guide and the QueryClient reference so you can compare initialData with imperative cache population. If you are preserving UI continuity across pages or IDs, read the paginated queries and render optimization pages next, because placeholder data often appears with key transitions and selective rendering. If you are debugging unexpected refetches, review cache lifecycle and important defaults, especially stale time, freshness, observers, and background updates. The central rule is simple: persist real data, display placeholder data.