Overview
createProxyQueryCaller creates a type-safe query client with dot-notation access to all your endpoint groups. Each group exposes useQuery, useMutation, useSuspenseQuery, useInfiniteQuery, and prefetchQuery.
Hooks exist per group only: endpoints declared at the top level of defineApi({ endpoints }) have none, so declare the endpoints your components use inside a group.
Step 1: Install @tanstack/react-query
React Query is a peer dependency, version 5.80 or later — install it alongside Courier:
npm install @tanstack/react-queryStep 2: Set up QueryClientProvider
React Query requires a QueryClientProvider at the root of your app. Create a client component that wraps your layout:
// app/providers.tsx
"use client"
import { QueryClient, QueryClientProvider } from "@noverax/courier-react"
import { useState, type ReactNode } from "react"
export function Providers({ children }: { children: ReactNode }) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000,
retry: 1,
},
},
})
)
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
)
}// app/layout.tsx
import { Providers } from "./providers"
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
)
}Step 3: Create the Courier query caller
Call createProxyQueryCaller with your API type and a source name. Export the query client from a single file so every component imports from the same place:
// lib/query.ts
import { createProxyQueryCaller } from "@noverax/courier-react"
import type { api } from "@/api"
export const q = createProxyQueryCaller<typeof api>("api")Then use it in your components with dot-notation:
"use client"
import { q } from "@/lib/query"
export function UserList() {
const { data, isLoading } = q.users.useQuery("getAll")
// ...
}Single export file
Keep the query caller in one file. This ensures all components share the same client instance and defaults.
Configuring defaults
createProxyQueryCaller accepts an optional defaults object to configure the underlying proxy caller. These defaults apply to every request:
// lib/query.ts
import { createProxyQueryCaller } from "@noverax/courier-react"
import type { api } from "@/api"
export const q = createProxyQueryCaller<typeof api>("api", {
// Custom proxy route URL (default: "/api/request")
proxyPath: { http: "/api/my-proxy" },
// Request timeout in milliseconds
timeout: 10000,
// Include cookies in proxy requests
credentials: "include",
// Default headers for all requests
headers: {
"X-App-Version": "1.0.0",
},
// Global error handler
onError: async (error) => {
if (error.status === 401) {
window.location.href = "/login"
}
},
// Global success handler
onSuccess: (data) => {
console.log("Request succeeded:", data)
},
})Next steps
- useQuery — fetch data with type-safe queries
- useMutation — create, update, and delete with typed mutations
- Proxy Caller — the underlying proxy caller API