}
>
);
}
```
--------------------------------
### Examples of FunctionReference Usage
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/types.md
Demonstrates how to use FunctionReference to type-check Convex function calls.
```typescript
import { api } from "../convex/_generated/api";
// Type: FunctionReference<"query">
const queryRef = api.messages.list;
// Type: FunctionReference<"action">
const actionRef = api.weather.getSFWeather;
```
--------------------------------
### Mutation with useConvexMutation
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/INDEX.md
Example of performing a mutation using `useMutation` and `useConvexMutation` to send a message. It shows how to call the mutate function with arguments.
```typescript
const { mutate } = useMutation({
mutationFn: useConvexMutation(api.messages.send),
});
mutate({ body: "Hello", author: userId });
```
--------------------------------
### Type Safety Example
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/INDEX.md
Ensures type safety for query arguments and return types. The example shows type errors for missing or incorrect arguments, and the correct usage.
```typescript
// Type error: missing required argument
convexQuery(api.users.getById); // ❌
// Type error: wrong argument type
convexQuery(api.users.getById, { id: 123 }); // ❌
// Correct
convexQuery(api.users.getById, { id: "123" }); // ✓
```
--------------------------------
### useConvexQueries Example
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-hooks.md
Utilize the useConvexQueries hook to subscribe to multiple Convex queries simultaneously. It returns an array of results corresponding to the input queries.
```typescript
import { useConvexQueries } from "@convex-dev/react-query";
import { api } from "../convex/_generated/api";
function Dashboard() {
const [messages, users] = useConvexQueries([
{ funcRef: api.messages.list, args: {} },
{ funcRef: api.users.list, args: {} },
]);
return (
<>
Messages: {messages?.length}
Users: {users?.length}
>
);
}
```
--------------------------------
### Examples of FunctionArgs Extraction
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/types.md
Shows how to use FunctionArgs to infer the argument types for Convex functions.
```typescript
// Extracts: { id: string }
type Args1 = FunctionArgs;
// Extracts: { channel: string }
type Args2 = FunctionArgs;
// Extracts: {}
type Args3 = FunctionArgs;
```
--------------------------------
### Basic Mutation with useConvexMutation
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/usage-patterns.md
Use `useConvexMutation` to create a mutation function for a Convex action. This example demonstrates creating a new post with success and error handling.
```typescript
import { useMutation } from "@tanstack/react-query";
import { useConvexMutation } from "@convex-dev/react-query";
import { api } from "../convex/_generated/api";
function CreatePost() {
const createMutation = useConvexMutation(api.posts.create);
const { mutate, isPending } = useMutation({
mutationFn: createMutation,
onSuccess: (newPost) => {
console.log("Post created:", newPost);
},
onError: (error) => {
console.error("Failed to create post:", error);
},
});
return (
);
}
```
--------------------------------
### Basic Query (No Arguments)
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query.md
Use `convexQuery` for Convex queries that do not require arguments. This example fetches the current user's data.
```typescript
import { useQuery } from "@tanstack/react-query";
import { convexQuery } from "@convex-dev/react-query";
import { api } from "../convex/_generated/api";
function UserProfile() {
const { data: user, isPending, error } = useQuery(
convexQuery(api.user.current)
);
if (isPending) return
Loading...
;
if (error) return
Error: {error.message}
;
return
Welcome, {user?.name}!
;
}
```
--------------------------------
### Reactive Query Example
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/INDEX.md
Use `useQuery` with `convexQuery` for data that automatically updates when server-side query results change. No polling or manual refetching is needed.
```typescript
const { data } = useQuery(
convexQuery(api.messages.list, {})
);
// data automatically updates when new messages arrive on server
```
--------------------------------
### Global Configuration for convexQuery
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query.md
If default `queryFn` and `queryKeyHashFn` are not globally configured on `QueryClient`, you must spread them into the `useQuery` options. This example shows how to manually set `queryFn`.
```typescript
import { useQuery } from "@tanstack/react-query";
import { useQueryClient } from "@tanstack/react-query";
function MyComponent() {
const queryClient = useQueryClient();
const cqc = queryClient.getQueryCache().getObservers()[0]; // Not recommended
const { data } = useQuery({
...convexQuery(api.messages.list, {}),
queryFn: cqc.options.queryFn,
});
}
```
--------------------------------
### Basic Convex Action Usage
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-action.md
Use convexAction for Convex actions that do not require arguments. This example shows how to fetch weather data.
```typescript
import { useQuery } from "@tanstack/react-query";
import { convexAction } from "@convex-dev/react-query";
import { api } from "../convex/_generated/api";
function WeatherWidget() {
const { data: weather, isPending, error } = useQuery(
convexAction(api.weather.getSFWeather)
);
if (isPending) return
Loading weather...
;
if (error) return
Error: {error.message}
;
return (
San Francisco: {weather.fahrenheit}°F, {weather.condition}
);
}
```
--------------------------------
### Query with useSuspenseQuery
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query.md
Example of using `convexQuery` with `useSuspenseQuery` from TanStack Query for a suspenseful data fetching experience. This requires wrapping the component in a `Suspense` boundary.
```typescript
import { useSuspenseQuery } from "@tanstack/react-query";
import { Suspense } from "react";
function MessageCountSuspense() {
const { data: count } = useSuspenseQuery(
convexQuery(api.messages.count, {})
);
return
{count} messages
;
}
function App() {
return (
Loading...}>
);
}
```
--------------------------------
### ConvexProvider and QueryClientProvider Setup
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/configuration.md
Wrap your application with ConvexProvider and QueryClientProvider to integrate Convex and React Query. Configure default options for queries, including a custom query key hash function.
```typescript
import { useConvexAuth } from "@convex-dev/react-query";
import { ConvexProvider } from "convex/react";
function App() {
const { isLoading, isAuthenticated } = useConvexAuth();
if (isLoading) return
Loading...
;
return
{isAuthenticated ? "Logged in" : "Logged out"}
;
}
// Wrap app with ConvexProvider
import { ConvexReactClient } from "convex/react";
import { ConvexQueryClient } from "@convex-dev/react-query";
import { QueryClientProvider } from "@tanstack/react-query";
const convexClient = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL);
const convexQueryClient = new ConvexQueryClient(convexClient);
const queryClient = new QueryClient({
defaultOptions: {
queries: {
queryKeyHashFn: convexQueryClient.hashFn(),
queryFn: convexQueryClient.queryFn(),
},
},
});
convexQueryClient.connect(queryClient);
export default (
);
```
--------------------------------
### Type Safety Examples
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query.md
Demonstrates compile-time type checking for Convex query arguments using `convexQuery`. Shows correct usage and common type errors.
```typescript
// ✅ Correct
const { data } = useQuery(
convexQuery(api.user.getById, { id: "123" })
);
// data is typed as the exact return type of api.user.getById
// ❌ Type error: missing required argument
const { data } = useQuery(
convexQuery(api.user.getById) // Error: 'id' is required
);
// ❌ Type error: wrong argument type
const { data } = useQuery(
convexQuery(api.user.getById, { id: 123 }) // Error: id should be string
);
// ❌ Type error: skip not allowed with UseQueryOptions usage
const { data } = useQuery({
...convexQuery(api.user.getById, "skip"),
enabled: false, // Redundant; "skip" already sets enabled: false
});
```
--------------------------------
### Query with Placeholder Data using Convex React Query
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/module-overview.md
This example shows how to provide placeholder data for a Convex query. Placeholder data is displayed until the actual query result is available.
```typescript
const { data } = useQuery({
...convexQuery(api.todos, { userId: "123" }),
placeholderData: [],
});
```
--------------------------------
### queryOptions
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query-client.md
A factory function that generates TanStack Query options specifically for Convex query subscriptions. It simplifies the setup by providing the necessary `queryKey`, `queryFn`, and `staleTime` for a given Convex query reference and its arguments.
```APIDOC
## queryOptions
### Description
Factory function to create TanStack Query options for a Convex query subscription.
### Method Signature
```ts
queryOptions>(
funcRef: ConvexQueryReference,
queryArgs: FunctionArgs
): Pick<
UseQueryOptions<
FunctionReturnType,
Error,
FunctionReturnType,
["convexQuery", ConvexQueryReference, FunctionArgs]
>,
"queryKey" | "queryFn" | "staleTime"
>
```
### Parameters
#### Path Parameters
- **funcRef** (`FunctionReference<"query">`) - Required - A reference to a Convex query function from the generated `api` object.
- **queryArgs** (`FunctionArgs`) - Required - Arguments to pass to the query function, extracted from the function's signature.
### Returns
An object with:
- `queryKey`: `["convexQuery", functionName, queryArgs]` (serializable)
- `queryFn`: The ConvexQueryClient's configured query function
- `staleTime`: `Infinity` (data is never stale; updated reactively)
### Example
```ts
import { useQuery } from "@tanstack/react-query";
import { api } from "../convex/_generated/api";
function MyComponent() {
const { data } = useQuery(
convexQueryClient.queryOptions(api.messages.list, {})
);
// Or spread to customize further:
const { data } = useQuery({
...convexQueryClient.queryOptions(api.messages.list, {}),
placeholderData: [],
});
}
```
```
--------------------------------
### Non-Reactive Action Example
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/INDEX.md
Use `useQuery` with `convexAction` for operations like third-party API calls or side effects that should execute once. It follows standard TanStack Query semantics.
```typescript
const { data } = useQuery(
convexAction(api.weather.getSFWeather)
);
// Execute once, returns result; no further updates
```
--------------------------------
### useConvexQuery Example
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-hooks.md
Use the useConvexQuery hook to directly subscribe to Convex query results and receive reactive updates. This hook is distinct from TanStack Query's useQuery.
```typescript
import { useConvexQuery } from "@convex-dev/react-query";
import { api } from "../convex/_generated/api";
function MessageList() {
// Returns reactive updates directly from Convex
const messages = useConvexQuery(api.messages.list, {});
return (
{messages?.map((msg) => (
{msg.body}
))}
);
}
```
--------------------------------
### Controlling Refetch with useQuery
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-action.md
Manually control data refetching for Convex actions within useQuery. This example disables caching and uses a manual refetch button.
```typescript
import { useQueryClient, useQuery } from "@tanstack/react-query";
import { convexAction } from "@convex-dev/react-query";
function DataRefresher() {
const queryClient = useQueryClient();
const { data, refetch, isPending } = useQuery({
...convexAction(api.sync.pullLatestData, {}),
gcTime: 0, // Don't cache
});
return (
<>
Last synced: {data?.timestamp}
>
);
}
```
--------------------------------
### Instantiate ConvexQueryClient
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query-client.md
Demonstrates different ways to instantiate ConvexQueryClient, either by passing a URL string or a ConvexReactClient instance. It also shows how to provide a TanStack QueryClient during instantiation.
```typescript
import { ConvexReactClient } from "convex/react";
import { ConvexQueryClient } from "@convex-dev/react-query";
import { QueryClient } from "@tanstack/react-query";
// Option 1: Pass URL string
const convexQueryClient = new ConvexQueryClient("https://your-project.convex.cloud");
// Option 2: Pass ConvexReactClient instance
const convexClient = new ConvexReactClient("https://your-project.convex.cloud");
const convexQueryClient = new ConvexQueryClient(convexClient);
// Option 3: With QueryClient in constructor
const queryClient = new QueryClient();
const convexQueryClient = new ConvexQueryClient("https://your-project.convex.cloud", {
queryClient,
});
```
--------------------------------
### Initialize ConvexQueryClient
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/configuration.md
Demonstrates three ways to initialize ConvexQueryClient: using a URL string, an existing ConvexReactClient instance, or with custom options like a QueryClient and serverFetch.
```typescript
import { ConvexReactClient } from "convex/react";
import { ConvexQueryClient } from "@convex-dev/react-query";
import { QueryClient } from "@tanstack/react-query";
// Option 1: URL string only
const cqc1 = new ConvexQueryClient("https://your-project.convex.cloud");
// Option 2: ConvexReactClient instance
const client = new ConvexReactClient("https://your-project.convex.cloud");
const cqc2 = new ConvexQueryClient(client);
// Option 3: With options
const cqc3 = new ConvexQueryClient("https://your-project.convex.cloud", {
queryClient: new QueryClient(),
serverFetch: globalThis.fetch,
});
```
--------------------------------
### Examples of FunctionReturnType Extraction
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/types.md
Illustrates using FunctionReturnType to infer the return types of Convex functions.
```typescript
// Extracts: User | null
type Return1 = FunctionReturnType;
// Extracts: Message[]
type Return2 = FunctionReturnType;
// Extracts: number
type Return3 = FunctionReturnType;
```
--------------------------------
### Single QueryClient Instance for Application
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/INDEX.md
Illustrates the correct pattern for creating a single QueryClient instance to be used throughout the application.
```typescript
// ❌ Bad: creates new instance each time
function App() {
const queryClient = new QueryClient();
return ;
}
// ✓ Good: single instance
const queryClient = new QueryClient();
export default ;
```
--------------------------------
### Correct QueryClient Initialization with Convex Defaults
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/INDEX.md
Shows the correct way to initialize a QueryClient with Convex-specific default options to avoid errors.
```typescript
// ❌ Error: "Query key is not for a Convex Query"
const queryClient = new QueryClient(); // No defaults!
// ✓ Correct
const queryClient = new QueryClient({
defaultOptions: {
queries: {
queryKeyHashFn: convexQueryClient.hashFn(),
queryFn: convexQueryClient.queryFn(),
},
},
});
```
--------------------------------
### Initialize ConvexQueryClient with ConvexReactClient Options
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/configuration.md
Shows how to pass ConvexReactClient options when initializing ConvexQueryClient with a URL string, including options like queryClient, serverFetch, and dangerouslyUseInconsistentQueriesDuringSSR.
```typescript
const cqc = new ConvexQueryClient("https://your-project.convex.cloud", {
queryClient,
serverFetch,
dangerouslyUseInconsistentQueriesDuringSSR: true,
// ConvexReactClientOptions also supported
});
```
--------------------------------
### Reactive Data Flow for Queries
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/module-overview.md
Details the step-by-step process from a `useQuery` hook mounting to a component re-rendering with updated data via Convex subscriptions.
```plaintext
1. useQuery(convexQuery(...)) mounts
↓
2. TanStack Query cache creates query entry
↓
3. ConvexQueryClient.subscribeInner() detects "added" event
↓
4. convexClient.watchQuery() creates WebSocket subscription
↓
5. Server monitors query and pushes updates
↓
6. watch.onUpdate() callback fires
↓
7. ConvexQueryClient.onUpdateQueryKeyHash() sets query data
↓
8. TanStack Query notifies React components
↓
9. Component re-renders with new data
```
--------------------------------
### Watch
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/types.md
Represents a subscription watch instance for Convex queries. It provides methods to get the current result and subscribe to updates.
```APIDOC
## Watch
### Description
Type representing a Convex subscription watch instance.
```ts
type Watch = {
localQueryResult(): T;
onUpdate(callback: () => void): () => void;
}
```
### Methods
| Name | Signature | Description |
|------|-----------|-------------|
| localQueryResult | `() => T` | Returns the current cached query result or throws an error if not ready |
| onUpdate | `(callback: () => void) => () => void` | Registers a callback for updates; returns an unsubscribe function |
### Source
Imported from `convex/react`
### Used internally by
`ConvexQueryClient` for managing subscriptions.
```
--------------------------------
### ConvexQueryClient Constructor Overloads
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/module-overview.md
Shows the different ways to instantiate the ConvexQueryClient, accepting either a ConvexReactClient instance or a URL.
```typescript
// new ConvexQueryClient(client: ConvexReactClient, options?: ConvexQueryClientOnlyOptions)
// new ConvexQueryClient(url: string, options?: ConvexQueryClientOptions)
```
--------------------------------
### ConvexQueryClient Constructor
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query-client.md
Initializes a new ConvexQueryClient instance. It can be initialized with either a ConvexReactClient instance or a URL string. Options can be provided to configure the client, including the TanStack QueryClient and custom fetch implementations.
```APIDOC
## ConvexQueryClient Constructor
### `ConvexQueryClient(client, options)`
Initializes a new ConvexQueryClient.
#### Parameters
- **client** (`ConvexReactClient | string`): Required. A ConvexReactClient instance or a URL string to create one. If a string is provided, a new ConvexReactClient will be instantiated with that URL.
- **options** (`ConvexQueryClientOnlyOptions | ConvexQueryClientOptions`): Optional. Configuration options for the client. When `client` is a string, supports full `ConvexQueryClientOptions` (including ConvexReactClientOptions). When `client` is a ConvexReactClient, supports only `ConvexQueryClientOnlyOptions`.
##### Options Details
- **queryClient** (`QueryClient`): Optional. The TanStack QueryClient to connect. Can also be set later via `.connect()`.
- **serverFetch** (`typeof globalThis.fetch`): Optional. Custom fetch implementation for server-side HTTP requests. Helps avoid bundling fetch on the client.
- **dangerouslyUseInconsistentQueriesDuringSSR** (`boolean`): Optional. Set to `true` to opt out of consistent queries during SSR for faster rendering, at the cost of potential data inconsistency. Default: `false`.
### Request Example
```ts
import { ConvexReactClient } from "convex/react";
import { ConvexQueryClient } from "@convex-dev/react-query";
import { QueryClient } from "@tanstack/react-query";
// Option 1: Pass URL string
const convexQueryClient = new ConvexQueryClient("https://your-project.convex.cloud");
// Option 2: Pass ConvexReactClient instance
const convexClient = new ConvexReactClient("https://your-project.convex.cloud");
const convexQueryClient = new ConvexQueryClient(convexClient);
// Option 3: With QueryClient in constructor
const queryClient = new QueryClient();
const convexQueryClient = new ConvexQueryClient("https://your-project.convex.cloud", {
queryClient,
});
```
```
--------------------------------
### Global Configuration for Convex Actions
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-action.md
Provides the necessary global configuration for `convexAction` using `QueryClient` defaults, similar to `convexQuery`.
```typescript
const queryClient = new QueryClient({
defaultOptions: {
queries: {
queryFn: convexQueryClient.queryFn(),
queryKeyHashFn: convexQueryClient.hashFn(),
},
},
});
```
--------------------------------
### Convex Query and Action Keys
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/INDEX.md
Illustrates the structure of query keys for Convex Queries and Actions, including how to skip them.
```typescript
// Convex Query
["convexQuery", FunctionReference<"query">, args]
// Convex Action
["convexAction", FunctionReference<"action">, args]
// Skip (disabled)
["convexQuery" | "convexAction", FunctionReference, "skip"]
```
--------------------------------
### Configure Vite for Development
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/configuration.md
Set up Vite configuration for development, defining the VITE_CONVEX_URL to point to your local Convex instance. This ensures your development environment connects correctly.
```typescript
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
define: {
"import.meta.env.VITE_CONVEX_URL": JSON.stringify(
process.env.VITE_CONVEX_URL || "http://localhost:3210"
),
},
});
```
--------------------------------
### ConvexReactClientOptions
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/types.md
Defines the options available for initializing the ConvexReactClient, allowing for configuration of the Convex SDK within a React environment.
```APIDOC
## ConvexReactClientOptions
### Description
Options for initializing a ConvexReactClient.
```ts
interface ConvexReactClientOptions {
// Convex SDK configuration options
}
```
### Source
Imported from `convex/react`
### Used by
[`ConvexQueryClientOptions`](#convexqueryclientoptions) when extending options.
```
--------------------------------
### File Organization Structure
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/README.md
Illustrates the directory structure of the Convex React Query project, highlighting the purpose of each main file and the organization of API reference documents.
```text
output/
├── INDEX.md ← Start here
├── README.md ← This file
├── module-overview.md ← Architecture & concepts
├── configuration.md ← Setup & options
├── usage-patterns.md ← Code examples
├── types.md ← Type definitions
└── api-reference/
├── convex-query-client.md ← ConvexQueryClient class
├── convex-query.md ← convexQuery() function
├── convex-action.md ← convexAction() function
└── convex-hooks.md ← Re-exported hooks
```
--------------------------------
### Mutation with Query Invalidation
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/usage-patterns.md
After a mutation succeeds, invalidate related queries to ensure data is refetched. This example invalidates the `api.todos.list` query upon updating a todo.
```typescript
function UpdateTodo({ todoId }: { todoId: string }) {
const queryClient = useQueryClient();
const updateMutation = useConvexMutation(api.todos.update);
const { mutate } = useMutation({
mutationFn: updateMutation,
onSuccess: () => {
// Invalidate related queries so they refetch
queryClient.invalidateQueries({
queryKey: ["convexQuery", api.todos.list],
});
},
});
return (
);
}
```
--------------------------------
### connect Method
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query-client.md
Completes the initialization of the ConvexQueryClient by connecting a TanStack QueryClient. This method subscribes to query cache events and synchronizes them with Convex subscriptions.
```APIDOC
## connect Method
### `connect(queryClient)`
Completes initialization by connecting a TanStack QueryClient to the ConvexQueryClient.
#### Parameters
- **queryClient** (`QueryClient`): Required. The TanStack QueryClient to connect. Subscribes to query cache events.
#### Throws
- **`Error`**: If already subscribed (`.connect()` called twice).
### Request Example
```ts
const convexQueryClient = new ConvexQueryClient(convexClient);
const queryClient = new QueryClient();
convexQueryClient.connect(queryClient);
// Now the QueryClient is synchronized with Convex subscriptions
```
```
--------------------------------
### Configure TanStack Query Global Defaults
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/configuration.md
Sets up global defaults for TanStack Query, including the required queryKeyHashFn and queryFn from ConvexQueryClient, and recommended staleTime and gcTime.
```typescript
import { QueryClient } from "@tanstack/react-query";
import { ConvexQueryClient } from "@convex-dev/react-query";
const convexQueryClient = new ConvexQueryClient("https://your-project.convex.cloud");
const queryClient = new QueryClient({
defaultOptions: {
queries: {
// Required: Use ConvexQueryClient's hash function
queryKeyHashFn: convexQueryClient.hashFn(),
// Required: Use ConvexQueryClient's query function
queryFn: convexQueryClient.queryFn(),
// Recommended: Set staleTime
// Note: convexQuery() automatically sets staleTime: Infinity
// This is for non-Convex queries
staleTime: 1000 * 60 * 5, // 5 minutes
// Optional: Garbage collection time
// How long to keep query results in cache after unmount
gcTime: 1000 * 60 * 10, // 10 minutes (default)
},
},
});
convexQueryClient.connect(queryClient);
```
--------------------------------
### Connecting QueryClient to ConvexQueryClient
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/INDEX.md
Demonstrates the correct procedure for connecting a TanStack QueryClient to a ConvexQueryClient instance.
```typescript
// ❌ Error when accessing convexQueryClient.queryClient
const cqc = new ConvexQueryClient(url);
// cqc.queryClient throws
// ✓ Correct: connect first
cqc.connect(queryClient);
```
--------------------------------
### Polling Convex Action Results
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-action.md
Implement polling for Convex action results by setting `refetchInterval` in the useQuery options. This example polls job status every 5 seconds.
```typescript
import { useQuery } from "@tanstack/react-query";
import { convexAction } from "@convex-dev/react-query";
function PollingJob() {
const { data: status, isRefetching } = useQuery({
...convexAction(api.jobs.getStatus, { jobId: "123" }),
refetchInterval: 5000, // Poll every 5 seconds
refetchIntervalPaused: false,
});
return (
);
}
```
--------------------------------
### Simple Action Fetching with useQuery
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/usage-patterns.md
Fetch data from a Convex action using `useQuery` combined with `convexAction`. This is suitable for read-only operations that don't require complex state management.
```typescript
import { useQuery } from "@tanstack/react-query";
import { convexAction } from "@convex-dev/react-query";
import { api } from "../convex/_generated/api";
function WeatherWidget() {
const { data: weather, isPending } = useQuery(
convexAction(api.weather.getSFWeather)
);
if (isPending) return
Loading weather...
;
return
SF: {weather?.temperature}°F
;
}
```
--------------------------------
### Custom Query Function for Non-Convex Queries
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/configuration.md
Configure ConvexQueryClient with a custom query function to handle non-Convex queries. This allows you to integrate other data sources or APIs within your React Query setup.
```typescript
const cqc = new ConvexQueryClient("https://...");
const queryClient = new QueryClient({
defaultOptions: {
queries: {
queryKeyHashFn: cqc.hashFn(),
queryFn: cqc.queryFn(async (context) => {
// Fallback for non-Convex queries
if (context.queryKey[0] === "custom") {
const [_, endpoint, params] = context.queryKey;
const res = await fetch(`/api/${endpoint}`, {
body: JSON.stringify(params),
});
return res.json();
}
throw new Error("Unknown query key");
}),
},
},
});
```
--------------------------------
### Access Convex Client with useConvex
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-hooks.md
Use the `useConvex` hook to get the underlying ConvexReactClient instance. This is useful for calling raw client methods like queries and mutations directly within your React components.
```typescript
import { useConvex } from "@convex-dev/react-query";
function CustomQuery() {
const convex = useConvex();
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
convex.query(api.messages.list, {})
.then(setData)
.finally(() => setLoading(false));
}, [convex]);
return
{loading ? "Loading..." : JSON.stringify(data)}
;
}
```
--------------------------------
### Get Authentication Status with useConvexAuth
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-hooks.md
The `useConvexAuth` hook provides the current authentication state. It returns an object with `isLoading` and `isAuthenticated` booleans, allowing you to conditionally render UI based on the user's login status.
```typescript
import { useConvexAuth } from "@convex-dev/react-query";
function AuthStatus() {
const { isLoading, isAuthenticated } = useConvexAuth();
if (isLoading) return
Checking auth...
;
return (
{isAuthenticated ? "Logged in" : "Logged out"}
);
}
```
--------------------------------
### Action Execution Timing and Refetching
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-action.md
Shows how to configure `convexAction` with TanStack Query options to control execution timing and refetching behavior.
```typescript
const { data, refetch, isFetching } = useQuery({
...convexAction(api.expensiveOperation, {}),
refetchOnMount: true, // Refetch when component mounts
refetchOnWindowFocus: true, // Refetch when window regains focus
refetchOnReconnect: true, // Refetch when reconnected
});
```
--------------------------------
### Use useQuery with Convex Query Options
Source: https://github.com/get-convex/convex-react-query/blob/main/README.md
Utilize the `useQuery` hook with the `convexQuery` options factory to fetch data from Convex. Set `gcTime` to control how long subscriptions remain active after unmounting.
```typescript
const { isPending, error, data } = useQuery({
...convexQuery(api.repos.get, { repo: "made/up" }),
gcTime: 10000, // unsubscribe after 10s of no use
});
```
--------------------------------
### Import ConvexQueryClient
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query-client.md
Import the ConvexQueryClient from the @convex-dev/react-query package.
```typescript
import { ConvexQueryClient } from "@convex-dev/react-query";
```
--------------------------------
### Query with Custom Options
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/usage-patterns.md
Fetches todos for a user and configures custom TanStack Query options like placeholder data and cache duration.
```typescript
function TodoList({ userId }: { userId: string }) {
const { data = [] } = useQuery({
...convexQuery(api.todos.listByUser, { userId }),
placeholderData: [], // Show empty list while loading
gcTime: 5 * 60 * 1000, // Cache for 5 minutes after unmount
});
return (
{data.map((todo) => (
{todo.title}
))}
);
}
```
--------------------------------
### Action with Manual Refetching
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/usage-patterns.md
Use `useQuery` with `convexAction` and enable manual refetching via the `refetch` function. This allows users to trigger data updates on demand.
```typescript
function DataSync() {
const { data: status, refetch, isPending } = useQuery({
...convexAction(api.sync.getStatus, {}),
refetchOnMount: false,
refetchOnWindowFocus: false,
});
return (
Last synced: {status?.timestamp}
);
}
```
--------------------------------
### Using convexQuery for TanStack Query Integration
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/INDEX.md
Shows the proper way to integrate Convex queries with TanStack Query using the `convexQuery` helper.
```typescript
// ❌ Not integrated with TanStack Query
const data = useConvexQuery(api.messages.list, {});
// ✓ Proper integration with TanStack Query
const { data } = useQuery(
convexQuery(api.messages.list, {})
);
```
--------------------------------
### Module Dependencies
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/module-overview.md
Lists the primary external dependencies for `src/index.ts`, including `@tanstack/react-query`, `convex/react`, and `convex/server`.
```plaintext
src/index.ts
├── @tanstack/react-query (external)
│ ├── QueryClient
│ ├── QueryCache
│ ├── QueryKey
│ └── QueryFunction
│
├── convex/react (external)
│ ├── ConvexReactClient
│ ├── Watch
│ ├── useQuery
│ ├── useConvexAuth
│ └── (other hooks)
│
└── convex/server (external)
├── FunctionReference
├── FunctionArgs
└── FunctionReturnType
```
--------------------------------
### ConvexReactClientOptions Interface
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/types.md
Options for initializing a ConvexReactClient. Used for configuring the client's behavior.
```typescript
interface ConvexReactClientOptions {
// Convex SDK configuration options
}
```
--------------------------------
### Simple Query (No Arguments)
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/usage-patterns.md
Fetches data for the current user without any arguments. Handles loading and error states.
```typescript
import { useQuery } from "@tanstack/react-query";
import { convexQuery } from "@convex-dev/react-query";
import { api } from "../convex/_generated/api";
function UserProfile() {
const { data: user, isPending, error } = useQuery(
convexQuery(api.user.getCurrentUser)
);
if (isPending) return
Loading...
;
if (error) return
Error: {error.message}
;
return
Hello, {user.name}!
;
}
```
--------------------------------
### Import convexQuery
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query.md
Import the `convexQuery` factory function from the `@convex-dev/react-query` package.
```typescript
import { convexQuery } from "@convex-dev/react-query";
```
--------------------------------
### Mocking ConvexQueryClient for Testing
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/usage-patterns.md
Create a mock ConvexQueryClient and QueryClient for unit testing React components that use Convex queries. This allows you to control query data and simulate different states.
```typescript
import { vi } from "vitest";
import { QueryClient } from "@tanstack/react-query";
function createMockConvexQueryClient() {
const queryClient = new QueryClient();
const mockClient = {
convexClient: {},
subscriptions: {},
connect: vi.fn(),
hashFn: () => (key: any) => JSON.stringify(key),
queryFn: () => async () => ({}),
queryOptions: vi.fn(),
};
return { mockClient, queryClient };
}
// Usage in test
it("renders with data", () => {
const { mockClient, queryClient } = createMockConvexQueryClient();
queryClient.setQueryData(
["convexQuery", api.todos.list, {}],
[{ _id: "1", title: "Test" }]
);
render(
);
expect(screen.getByText("Test")).toBeInTheDocument();
});
```
--------------------------------
### Import convexAction
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-action.md
Import the convexAction factory function from the @convex-dev/react-query package.
```typescript
import { convexAction } from "@convex-dev/react-query";
```
--------------------------------
### Non-Reactive Data Flow for Actions
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/module-overview.md
Explains the data flow for non-reactive actions, initiated by `useQuery(convexAction(...))`, which follows standard TanStack Query refetch semantics.
```plaintext
1. useQuery(convexAction(...)) runs
↓
2. TanStack Query calls queryFn
↓
3. ConvexQueryClient.queryFn() detects "convexAction" key
↓
4. convexClient.action() executes action and returns result
↓
5. Result stored in TanStack Query cache
↓
6. Component receives data
↓
7. No further updates unless manual refetch
```
--------------------------------
### Conditional Query Usage
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/INDEX.md
Demonstrates how to conditionally execute a query based on a variable. If `search` is falsy, the query is skipped.
```typescript
const { data } = useQuery(
convexQuery(
api.search.results,
search ? { q: search } : "skip"
)
);
```
--------------------------------
### Custom Server Fetch with Authentication
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/configuration.md
Implement custom server-side fetch for ConvexQueryClient to include authentication headers. This is useful for securely accessing Convex from your server during SSR.
```typescript
import { ConvexQueryClient } from "@convex-dev/react-query";
// During SSR with custom fetch
const cqc = new ConvexQueryClient(
"https://your-project.convex.cloud",
{
serverFetch: async (url, options) => {
// Custom server-side fetch with auth headers, etc.
return fetch(url, {
...options,
headers: {
...options?.headers,
"Authorization": `Bearer ${process.env.CONVEX_AUTH_TOKEN}`,
},
});
},
}
);
```
--------------------------------
### Connect TanStack QueryClient
Source: https://github.com/get-convex/convex-react-query/blob/main/_autodocs/api-reference/convex-query-client.md
Connects a TanStack QueryClient to the ConvexQueryClient to synchronize subscriptions. This method should only be called once.
```typescript
const convexQueryClient = new ConvexQueryClient(convexClient);
const queryClient = new QueryClient();
convexQueryClient.connect(queryClient);
// Now the QueryClient is synchronized with Convex subscriptions
```