React Query
Officialv5.8.0@kubb/plugin-react-query
Options
Pass these options to pluginReactQuery(). Shared options link to Shared plugin options for details.
Options overview
| Option | Purpose | Default |
|---|---|---|
output | Where files are written: path, mode, barrel, banner, footer. | { path: 'hooks', barrel: { type: 'named' } } |
group | Split output by tag or path: type, name. | None |
client | Which registered client plugin the hooks call. | Auto-detected |
infinite | Generate useInfiniteQuery hooks for pagination. | false |
suspense | Generate useSuspenseQuery hooks. | false |
query | Configure the query hooks. | { methods: ['GET', 'QUERY'], importPath: '@tanstack/react-query' } |
queryKey | Build the queryKey for each query hook. | Exported queryKeyTransformer |
mutation | Configure the mutation hooks. | { methods: ['POST', 'PUT', 'PATCH', 'DELETE'], importPath: '@tanstack/react-query' } |
mutationKey | Build the mutationKey for each mutation hook. | Exported mutationKeyTransformer |
customOptions | Route every hook through your own options function. | None |
hooks | Emit use* hook functions on top of the factories. | false |
include | Keep only operations that match. | None |
exclude | Skip operations that match. | [] |
override | Apply different options per pattern. | [] |
resolver | Customize generated names and file paths. | resolverReactQuery |
macros | Rewrite AST nodes before printing. | [] |
Option details
client
Selects which registered client plugin the hooks call. A single registered client is auto-detected. Set client when several are registered.
| Type | 'fetch' | 'axios' | 'client' |
| Required | false |
@kubb/plugin-fetch.@kubb/plugin-axios.@kubb/plugin-client. Your client module must also export the RequestConfig and ResponseErrorConfig types.infinite
Adds infiniteQueryOptions and useInfiniteQuery for operations that declare the query parameter named in infinite.queryParam. Needs hooks: true.
| Type | Partial<Infinite> | false |
| Required | false |
| Default | false |
infinite.queryParam
Query parameter that carries the page cursor.
| Type | string |
| Required | false |
| Default | 'id' |
infinite.initialPageParam
Initial value for pageParam on the first fetch.
| Type | unknown |
| Required | false |
| Default | 0 |
infinite.nextParam
Path to the next-page cursor on the response, as dot notation ('pagination.next.id') or array form (['pagination', 'next', 'id']).
| Type | string | Array<string> | null |
| Required | false |
| Default | null |
infinite.previousParam
Path to the previous-page cursor on the response, in the same dot or array form.
| Type | string | Array<string> | null |
| Required | false |
| Default | null |
infinite.cursorParam
Deprecated path to the cursor field, read for both getNextPageParam and getPreviousPageParam when set. Use nextParam and previousParam instead.
| Type | string | null |
| Required | false |
| Default | null |
infinite.getNextPageParam
Source code for TanStack Query's getNextPageParam, copied into the generated code as written. Use it when the next page must be computed instead of read from a field. Takes precedence over nextParam and cursorParam.
| Type | string | null |
| Required | false |
| Default | null |
infinite: {
queryParam: 'page',
getNextPageParam: '(lastPage) => (lastPage.hasNext ? lastPage.number + 1 : undefined)',
getPreviousPageParam: '(firstPage) => (firstPage.number > 0 ? firstPage.number - 1 : undefined)',
}Without getNextPageParam, nextParam or cursorParam, the hook counts pages up from initialPageParam until a page is an empty array. This works only for array responses, so generation warns when the response is an object.
infinite.getPreviousPageParam
Source code for TanStack Query's getPreviousPageParam, copied into the generated code as written. Takes precedence over previousParam and cursorParam.
| Type | string | null |
| Required | false |
| Default | null |
suspense
Adds useSuspenseQuery hooks next to the regular query hooks. Pass {} to turn it on. Needs TanStack Query v5 or higher and hooks: true.
| Type | Partial<object> | false |
| Required | false |
| Default | false |
query
Which operations become queries, emitting a queryOptions factory by default. Pass false to skip, or set hooks to also emit useQuery.
| Type | Partial<Query> | false |
| Required | false |
| Default | { methods: ['GET', 'QUERY'], importPath: '@tanstack/react-query' } |
query.methods
HTTP methods treated as queries.
| Type | Array<string> |
| Required | false |
| Default | ['GET', 'QUERY'] |
Operations whose method is in neither query.methods nor mutation.methods get no hook. Keep 'QUERY' here when overriding the list, or QUERY operations are skipped.
query.importPath
Module for the queryOptions and useQuery imports.
| Type | string |
| Required | false |
| Default | '@tanstack/react-query' |
queryKey
Builds the queryKey for each hook from the operation node, casing and variant. Strings are copied into the generated code as written, so wrap a string literal in JSON.stringify(...).
| Type | (props: { node, casing, variant }) => Array<unknown> |
| Required | false |
| Default | Exported queryKeyTransformer |
variant is 'query', 'suspenseQuery', 'infiniteQuery' or 'suspenseInfiniteQuery'. The default key adds infinite: true to infinite variants so they never share a cache entry with the plain query.
queryKey: ({ node, variant }) => [JSON.stringify({ variant, operationId: node.operationId })]To extend the default key instead of replacing it, import queryKeyTransformer and spread its result. The default segments can change between releases, so spread them instead of reading single entries.
import { queryKeyTransformer } from '@kubb/plugin-react-query'
queryKey: (props) => [JSON.stringify(props.node.operationId), ...queryKeyTransformer(props)]mutation
Which operations become mutations, emitting a mutationOptions factory by default. Set false to skip, or set hooks to also emit useMutation.
| Type | Partial<Mutation> | false |
| Required | false |
| Default | { methods: ['POST', 'PUT', 'PATCH', 'DELETE'], importPath: '@tanstack/react-query' } |
mutation.methods
HTTP methods treated as mutations.
| Type | Array<string> |
| Required | false |
| Default | ['POST', 'PUT', 'PATCH', 'DELETE'] |
mutation.importPath
Module for the mutationOptions and useMutation imports.
| Type | string |
| Required | false |
| Default | '@tanstack/react-query' |
mutationKey
Builds the mutationKey for each mutation hook, for batched invalidations or useMutationState. Same props and string-inlining caveat as queryKey, with variant set to 'mutation'.
| Type | (props: { node, casing, variant }) => Array<unknown> |
| Required | false |
| Default | Exported mutationKeyTransformer |
Extend the default the same way with mutationKeyTransformer:
import { mutationKeyTransformer } from '@kubb/plugin-react-query'
mutationKey: (props) => [JSON.stringify(props.node.operationId), ...mutationKeyTransformer(props)]customOptions
Routes every hook through your own function that returns extra options such as onSuccess or select. Also emits a HookOptions type that maps each hook name to its options type. Needs hooks: true.
| Type | { importPath: string, name?: string } |
| Required | false |
customOptions.importPath
Module of your custom-options hook, imported as a named import. It resolves from the generated hooks folder. When the module does not exist yet, Kubb writes a starter file there, but only when importPath stays inside the plugin's output folder. For a path outside it, create the module yourself.
| Type | string |
| Required | true when customOptions is set |
customOptions.name
Exported name of your custom-options hook.
| Type | string |
| Required | false |
| Default | 'useCustomHookOptions' |
hooks
When false (the default), only the queryOptions, mutationOptions, queryKey and mutationKey helpers are written, using factory imports that work across TanStack Query adapters. Set true to also generate useQuery, useSuspenseQuery, useInfiniteQuery, useSuspenseInfiniteQuery, and useMutation.
| Type | boolean |
| Required | false |
| Default | false |
resolver
Overrides generated file and symbol names. Omitted members keep resolverReactQuery. The shared members (name, file, imports) and the this context are described under resolver.
| Type | ResolverPatch<ResolverReactQuery> |
| Required | false |
type ResolverReactQueryPatch = {
// plus the shared name, file, and imports members
query?: {
name?(node: OperationNode): string // → 'useGetPetById'
optionsName?(node: OperationNode): string // → 'getPetByIdQueryOptions'
keyName?(node: OperationNode): string // → 'getPetByIdQueryKey'
keyTypeName?(node: OperationNode): string // → 'GetPetByIdQueryKey'
}
// suspenseQuery, infiniteQuery, suspenseInfiniteQuery: same members as query
mutation?: {
name?(node: OperationNode): string // → 'useUpdatePet'
optionsName?(node: OperationNode): string
keyName?(node: OperationNode): string
}
hook?: {
optionsName?(): string
customOptionsName?(): string
}
}