Skip to content

feat(vue-query): add usePrefetchQuery and usePrefetchInfiniteQuery#10372

Open
thalassophilia wants to merge 3 commits intoTanStack:mainfrom
thalassophilia:feat/vue-prefetch-composables
Open

feat(vue-query): add usePrefetchQuery and usePrefetchInfiniteQuery#10372
thalassophilia wants to merge 3 commits intoTanStack:mainfrom
thalassophilia:feat/vue-prefetch-composables

Conversation

@thalassophilia
Copy link
Copy Markdown

@thalassophilia thalassophilia commented Apr 1, 2026

🎯 Changes

Add usePrefetchQuery and usePrefetchInfiniteQuery to @tanstack/vue-query.

This PR:

  • adds usePrefetchQuery and usePrefetchInfiniteQuery to the Vue adapter
  • supports reactive options via refs and getters
  • only prefetches when the query state does not already exist in the cache
  • adds runtime and type tests for both composables
  • adds Vue reference docs for both APIs

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Validated with:

  • npx nx run @tanstack/vue-query:test:lib
  • npx nx run @tanstack/vue-query:test:eslint

Summary by CodeRabbit

  • New Features

    • Added reactive prefetch composables: usePrefetchQuery and usePrefetchInfiniteQuery.
  • Documentation

    • Added Vue API reference pages for both new composables and updated navigation.
  • Tests

    • Added unit tests and TypeScript declaration tests covering behavior, reactivity, and typings.
  • Chores

    • Added release metadata entry marking a minor release.

@github-actions github-actions bot added documentation Improvements or additions to documentation package: vue-query labels Apr 1, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 1, 2026

📝 Walkthrough

Walkthrough

Adds two Vue prefetch composables—usePrefetchQuery and usePrefetchInfiniteQuery—their option types and exports, Vue reference docs and nav entries, a changeset for a minor release, and runtime + TypeScript tests validating reactive behavior, cache checks, and dev-mode warnings.

Changes

Cohort / File(s) Summary
Changesets & Release Metadata
\.changeset/puny-poems-tell.md
New changeset declaring a minor release that introduces usePrefetchQuery and usePrefetchInfiniteQuery.
Docs & Navigation
docs/config.json, docs/framework/vue/reference/usePrefetchQuery.md, docs/framework/vue/reference/usePrefetchInfiniteQuery.md
Added Vue reference pages and navigation entries for both hooks (adapted/ref links to React docs); removed one ESLint nav child entry.
Composable Implementations
packages/vue-query/src/usePrefetchQuery.ts, packages/vue-query/src/usePrefetchInfiniteQuery.ts
New composables and exported option types that accept maybe-refs/getters, warn in dev when outside a Vue effect scope, deep-clone/unref resolved options, check client.getQueryState(...), and call client.prefetchQuery / client.prefetchInfiniteQuery only when no state exists.
Public API Exports
packages/vue-query/src/index.ts
Added named exports and type-only re-exports for the two new hooks and their option types.
Tests — Runtime & Type
packages/vue-query/src/__tests__/*prefetch*.test.ts, packages/vue-query/src/__tests__/*prefetch*.test-d.ts
Added Vitest runtime suites and TypeScript declaration tests covering prefetch behavior, reactive key unwrapping, cache checks, reactive re-execution on ref changes, dev-mode scope warnings, and type-level constraints (including rejection of skipToken and disallowed options).

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant Vue as Vue (effect/watchEffect)
    participant Composable as Prefetch Composable
    participant QC as QueryClient

    Dev->>Composable: invoke(options: maybe refs or getter)
    Composable->>Vue: create watchEffect to resolve options
    Vue->>Composable: resolved options (deep-unref/cloned)
    Composable->>QC: getQueryState(resolved.queryKey)
    QC-->>Composable: state (exists / undefined)
    alt state undefined
        Composable->>QC: prefetchQuery / prefetchInfiniteQuery(clonedOptions)
        QC-->>Composable: prefetch result
    else state exists
        Composable-->>Dev: no-op (skip prefetch)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped through refs and unwrapped the lot,

Prefetched pages where cache was not,
Docs and tests lined up in a row,
A tiny changelog stamp to show,
I twitch my nose and watch it go.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main changes: adding two new Vue composables (usePrefetchQuery and usePrefetchInfiniteQuery) to vue-query.
Description check ✅ Passed The PR description follows the template structure with all required sections completed: Changes, Checklist, and Release Impact sections are present with substantive details provided.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/config.json (1)

1271-1305: ⚠️ Potential issue | 🟠 Major

Re-add Prefer Query Options to ESLint navigation.

The ESLint rule is active in packages/eslint-plugin-query/src/index.ts and packages/eslint-plugin-query/src/rules.ts, documented at docs/eslint/prefer-query-options.md and listed in docs/eslint/eslint-plugin-query.md, but missing from docs/config.json. This leaves the documentation page orphaned and undiscoverable in the navigation.

Proposed fix
         {
           "label": "Mutation Property Order",
           "to": "eslint/mutation-property-order"
+        },
+        {
+          "label": "Prefer Query Options",
+          "to": "eslint/prefer-query-options"
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/config.json` around lines 1271 - 1305, Add the missing "Prefer Query
Options" nav entry to docs/config.json so the documentation page is
discoverable: locate the ESLint section children array (where other rules like
"ESLint Plugin Query", "Exhaustive Deps", and "Stable Query Client" are listed)
and insert an object with "label": "Prefer Query Options" and "to":
"eslint/prefer-query-options"; this corresponds to the existing rule
implementation in packages/eslint-plugin-query/src/index.ts and
packages/eslint-plugin-query/src/rules.ts and the docs file
docs/eslint/prefer-query-options.md.
🧹 Nitpick comments (1)
packages/vue-query/src/usePrefetchQuery.ts (1)

29-31: Consider extracting isGetter into a shared internal helper.

This helper is duplicated in packages/vue-query/src/usePrefetchInfiniteQuery.ts; centralizing it would reduce drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/vue-query/src/usePrefetchQuery.ts` around lines 29 - 31, The
isGetter helper is duplicated (function isGetter and its MaybeRefOrGetter usage)
— extract it into a single internal helper module (e.g., an internal utils file)
that exports isGetter<T>(value: MaybeRefOrGetter<T>): value is () => T and the
needed types, then replace the local implementations in usePrefetchQuery
(function isGetter) and usePrefetchInfiniteQuery with imports from that shared
helper and remove the duplicate definitions so both files consume the same
utility.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@docs/config.json`:
- Around line 1271-1305: Add the missing "Prefer Query Options" nav entry to
docs/config.json so the documentation page is discoverable: locate the ESLint
section children array (where other rules like "ESLint Plugin Query",
"Exhaustive Deps", and "Stable Query Client" are listed) and insert an object
with "label": "Prefer Query Options" and "to": "eslint/prefer-query-options";
this corresponds to the existing rule implementation in
packages/eslint-plugin-query/src/index.ts and
packages/eslint-plugin-query/src/rules.ts and the docs file
docs/eslint/prefer-query-options.md.

---

Nitpick comments:
In `@packages/vue-query/src/usePrefetchQuery.ts`:
- Around line 29-31: The isGetter helper is duplicated (function isGetter and
its MaybeRefOrGetter usage) — extract it into a single internal helper module
(e.g., an internal utils file) that exports isGetter<T>(value:
MaybeRefOrGetter<T>): value is () => T and the needed types, then replace the
local implementations in usePrefetchQuery (function isGetter) and
usePrefetchInfiniteQuery with imports from that shared helper and remove the
duplicate definitions so both files consume the same utility.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 869bf223-c4fc-42b4-8411-9df0a52c28a0

📥 Commits

Reviewing files that changed from the base of the PR and between 67b12ae and cfc42ae.

📒 Files selected for processing (11)
  • .changeset/puny-poems-tell.md
  • docs/config.json
  • docs/framework/vue/reference/usePrefetchInfiniteQuery.md
  • docs/framework/vue/reference/usePrefetchQuery.md
  • packages/vue-query/src/__tests__/usePrefetchInfiniteQuery.test-d.ts
  • packages/vue-query/src/__tests__/usePrefetchInfiniteQuery.test.ts
  • packages/vue-query/src/__tests__/usePrefetchQuery.test-d.ts
  • packages/vue-query/src/__tests__/usePrefetchQuery.test.ts
  • packages/vue-query/src/index.ts
  • packages/vue-query/src/usePrefetchInfiniteQuery.ts
  • packages/vue-query/src/usePrefetchQuery.ts

@thalassophilia thalassophilia force-pushed the feat/vue-prefetch-composables branch from cfc42ae to 9057679 Compare April 1, 2026 09:38
- Add usePrefetchQuery and usePrefetchInfiniteQuery to vue-query.
- Includes runtime and type tests, plus a changeset
@thalassophilia thalassophilia force-pushed the feat/vue-prefetch-composables branch from 9057679 to a72cdb5 Compare April 1, 2026 09:42
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/vue-query/src/usePrefetchQuery.ts (1)

29-31: Consider extracting isGetter helper to utils.

This helper is duplicated in usePrefetchInfiniteQuery.ts. Extracting it to utils.ts would reduce duplication.

♻️ Suggested refactor

In packages/vue-query/src/utils.ts:

+export function isGetter<T>(value: MaybeRefOrGetter<T>): value is () => T {
+  return typeof value === 'function'
+}

Then import and use in both composables.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/vue-query/src/usePrefetchQuery.ts` around lines 29 - 31, Extract the
duplicated isGetter helper into a shared utils module and import it from both
composables: create an exported isGetter<T>(value: MaybeRefOrGetter<T>): value
is () => T function in packages/vue-query/src/utils.ts, remove the local
isGetter definitions in usePrefetchQuery (function isGetter) and
usePrefetchInfiniteQuery, and update both files to import { isGetter } from
'./utils' so they share the single implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/vue-query/src/usePrefetchQuery.ts`:
- Around line 29-31: Extract the duplicated isGetter helper into a shared utils
module and import it from both composables: create an exported
isGetter<T>(value: MaybeRefOrGetter<T>): value is () => T function in
packages/vue-query/src/utils.ts, remove the local isGetter definitions in
usePrefetchQuery (function isGetter) and usePrefetchInfiniteQuery, and update
both files to import { isGetter } from './utils' so they share the single
implementation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6fa81406-de50-46da-afb2-d52566b4410d

📥 Commits

Reviewing files that changed from the base of the PR and between 9057679 and a72cdb5.

📒 Files selected for processing (11)
  • .changeset/puny-poems-tell.md
  • docs/config.json
  • docs/framework/vue/reference/usePrefetchInfiniteQuery.md
  • docs/framework/vue/reference/usePrefetchQuery.md
  • packages/vue-query/src/__tests__/usePrefetchInfiniteQuery.test-d.ts
  • packages/vue-query/src/__tests__/usePrefetchInfiniteQuery.test.ts
  • packages/vue-query/src/__tests__/usePrefetchQuery.test-d.ts
  • packages/vue-query/src/__tests__/usePrefetchQuery.test.ts
  • packages/vue-query/src/index.ts
  • packages/vue-query/src/usePrefetchInfiniteQuery.ts
  • packages/vue-query/src/usePrefetchQuery.ts
✅ Files skipped from review due to trivial changes (5)
  • docs/framework/vue/reference/usePrefetchQuery.md
  • docs/framework/vue/reference/usePrefetchInfiniteQuery.md
  • .changeset/puny-poems-tell.md
  • docs/config.json
  • packages/vue-query/src/tests/usePrefetchInfiniteQuery.test-d.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/vue-query/src/index.ts
  • packages/vue-query/src/tests/usePrefetchQuery.test-d.ts
  • packages/vue-query/src/tests/usePrefetchInfiniteQuery.test.ts
  • packages/vue-query/src/tests/usePrefetchQuery.test.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/config.json (1)

1283-1317: ⚠️ Potential issue | 🟠 Major

Re-add prefer-query-options to ESLint navigation.

The rule is still implemented and exported, but it is no longer listed in docs navigation. This de-lists a valid rule from the ESLint docs menu.

Suggested patch
         {
           "label": "Mutation Property Order",
           "to": "eslint/mutation-property-order"
+        },
+        {
+          "label": "Prefer Query Options",
+          "to": "eslint/prefer-query-options"
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/config.json` around lines 1283 - 1317, The ESLint navigation block under
the "ESLint" children array is missing the entry for the existing rule; add an
object for the prefer-query-options rule to that children list (e.g., label
"Prefer Query Options" and to "eslint/prefer-query-options") so the rule
exported by the codebase is listed in the docs navigation; update the children
array near the entries like "ESLint Plugin Query" / "Exhaustive Deps" / "Stable
Query Client" / "No Rest Destructuring" to include this new item.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@docs/config.json`:
- Around line 1283-1317: The ESLint navigation block under the "ESLint" children
array is missing the entry for the existing rule; add an object for the
prefer-query-options rule to that children list (e.g., label "Prefer Query
Options" and to "eslint/prefer-query-options") so the rule exported by the
codebase is listed in the docs navigation; update the children array near the
entries like "ESLint Plugin Query" / "Exhaustive Deps" / "Stable Query Client" /
"No Rest Destructuring" to include this new item.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a1d7b4b9-af69-4d03-b244-3ee50bb23cf0

📥 Commits

Reviewing files that changed from the base of the PR and between a72cdb5 and 1f1c4a7.

📒 Files selected for processing (1)
  • docs/config.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation package: vue-query

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant