Skip to content
tRPC

createTRPCQueryUtils

On this page

The use case for createTRPCQueryUtils is when you need to use the helpers outside of a React Component, for example in react-router's loaders.

Similar to useUtils, createTRPCQueryUtils is a function that gives you access to helpers that let you manage the cached data of the queries you execute via @trpc/react-query. These helpers are actually thin wrappers around @tanstack/react-query's queryClient methods. If you want more in-depth information about options and usage patterns for useUtils helpers than what we provide here, we will link to their respective @tanstack/react-query docs so you can refer to them accordingly.

The difference between useUtils and createTRPCQueryUtils is that useUtils is a react hook that uses useQueryClient under the hood. This means that it is able to work better within React Components.

If you need access to the client directly, you can use the client object that you passed to createTRPCQueryUtils during creation.

Usage

createTRPCQueryUtils returns an object with all the available queries you have in your routers. You use it the same way as your trpc client object. Once you reach a query, you'll have access to the query helpers. For example, let's say you have a post router with an all query:

Now in our route loader, when we navigate the object createTRPCQueryUtils gives us and reach the post.all query, we'll get access to our query helpers!

MyPage.tsx
import { class QueryClientQueryClient } from '@tanstack/react-query';
import { function createTRPCQueryUtils<TRouter extends AnyRouter>(opts: CreateQueryUtilsOptions<TRouter>): CreateQueryUtils<TRouter>createTRPCQueryUtils, function createTRPCReact<TRouter extends AnyRouter, TSSRContext = unknown>(opts?: CreateTRPCReactOptions<TRouter>): CreateTRPCReact<TRouter, TSSRContext>createTRPCReact } from '@trpc/react-query';
import type { 
type AppRouter = Router<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>> & DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>
AppRouter
} from './server';
const
const trpc: CreateTRPCReactBase<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>, unknown> & DecorateRouterRecord<...>
trpc
=
createTRPCReact<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>, unknown>(opts?: CreateTRPCReactOptions<...> | undefined): CreateTRPCReactBase<...> & DecorateRouterRecord<...>
createTRPCReact
<
type AppRouter = Router<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>> & DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>
AppRouter
>();
const
const trpcClient: TRPCClient<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>>
trpcClient
=
const trpc: CreateTRPCReactBase<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>, unknown> & DecorateRouterRecord<...>
trpc
.
createClient: (opts: CreateTRPCClientOptions<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>>) => TRPCClient<...>
createClient
({
links: TRPCLink<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>>[]
links
: [] });
const const queryClient: QueryClientqueryClient = new new QueryClient(config?: QueryClientConfig): QueryClientQueryClient(); const
const clientUtils: CreateQueryUtils<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>>
clientUtils
=
createTRPCQueryUtils<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>>(opts: CreateQueryUtilsOptions<...>): CreateQueryUtils<...>
createTRPCQueryUtils
({ CreateQueryUtilsOptions<TRouter extends AnyRouter>.queryClient: QueryClientqueryClient,
CreateQueryUtilsOptions<BuiltRouter<{ ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }, DecorateCreateRouterOptions<{ post: BuiltRouter<{ ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }, DecorateCreateRouterOptions<...>>; }>>>.client: TRPCClient<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>> | TRPCUntypedClient<...>
client
:
const trpcClient: TRPCClient<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>>
trpcClient
});
// This is a react-router loader export async function
function loader(): Promise<{
    allPostsData: {
        posts: {
            id: number;
            title: string;
        }[];
    };
}>
loader
() {
const
const allPostsData: {
    posts: {
        id: number;
        title: string;
    }[];
}
allPostsData
= await
const clientUtils: CreateQueryUtils<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>>
clientUtils
.
post: DecorateRouter & {
    all: DecorateQueryProcedure<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, QueryProcedure<{
        input: void;
        output: {
            posts: {
                id: number;
                title: string;
            }[];
        };
        meta: object;
        errorShape: DefaultErrorShape;
    }>>;
}
post
.
all: DecorateQueryProcedure<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, QueryProcedure<{
    input: void;
    output: {
        posts: {
            id: number;
            title: string;
        }[];
    };
    meta: object;
    errorShape: DefaultErrorShape;
}>>
all
.
function ensureData(input: void, opts?: TRPCFetchQueryOptions<{
    posts: {
        id: number;
        title: string;
    }[];
}, TRPCClientError<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}>> | undefined): Promise<{
    posts: {
        id: number;
        title: string;
    }[];
}>
ensureData
(); // Fetches data if it doesn't exist in the cache
return {
allPostsData: {
    posts: {
        id: number;
        title: string;
    }[];
}
allPostsData
,
}; } // This is a react component export function function Component(): React.JSX.ElementComponent() { const
const loaderData: {
    allPostsData: {
        posts: {
            id: number;
            title: string;
        }[];
    };
}
loaderData
= function useLoaderData(): unknownuseLoaderData() as
type Awaited<T> = T extends null | undefined ? T : T extends object & {
    then(onfulfilled: infer F, ...args: infer _): any;
} ? F extends (value: infer V, ...args: infer _) => any ? Awaited<V> : never : T
Awaited
<type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : anyReturnType<typeof
function loader(): Promise<{
    allPostsData: {
        posts: {
            id: number;
            title: string;
        }[];
    };
}>
loader
>>;
const
const allPostQuery: DefinedUseTRPCQueryResult<{
    posts: {
        id: number;
        title: string;
    }[];
}, TRPCClientErrorLike<{
    errorShape: DefaultErrorShape;
    transformer: false;
}>>
allPostQuery
=
const trpc: CreateTRPCReactBase<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        all: QueryProcedure<{
            input: void;
            output: {
                posts: {
                    id: number;
                    title: string;
                }[];
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>>, unknown> & DecorateRouterRecord<...>
trpc
.
post: DecorateRouterRecord<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    all: QueryProcedure<{
        input: void;
        output: {
            posts: {
                id: number;
                title: string;
            }[];
        };
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
post
.
all: DecoratedQuery<{
    input: void;
    output: {
        posts: {
            id: number;
            title: string;
        }[];
    };
    transformer: false;
    errorShape: DefaultErrorShape;
}>
all
.
useQuery: ProcedureUseQuery
<{
    posts: {
        id: number;
        title: string;
    }[];
}, {
    posts: {
        id: number;
        title: string;
    }[];
}>(input: void | unique symbol, opts: DefinedUseTRPCQueryOptions<{
    posts: {
        id: number;
        title: string;
    }[];
}, {
    posts: {
        id: number;
        title: string;
    }[];
}, TRPCClientErrorLike<{
    errorShape: DefaultErrorShape;
    transformer: false;
}>, {
    posts: {
        id: number;
        title: string;
    }[];
}>) => DefinedUseTRPCQueryResult<{
    posts: {
        id: number;
        title: string;
    }[];
}, TRPCClientErrorLike<{
    errorShape: DefaultErrorShape;
    transformer: false;
}>> (+1 overload)
useQuery
(var undefinedundefined, {
DefinedUseTRPCQueryOptions<{ posts: { id: number; title: string; }[]; }, { posts: { id: number; title: string; }[]; }, TRPCClientErrorLike<{ errorShape: DefaultErrorShape; transformer: false; }>, { posts: { id: number; title: string; }[]; }>.initialData: {
    posts: {
        id: number;
        title: string;
    }[];
} | InitialDataFunction<{
    posts: {
        id: number;
        title: string;
    }[];
}>
initialData
:
const loaderData: {
    allPostsData: {
        posts: {
            id: number;
            title: string;
        }[];
    };
}
loaderData
.
allPostsData: {
    posts: {
        id: number;
        title: string;
    }[];
}
allPostsData
, // Uses the data from the loader
}); return ( <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div> {
const allPostQuery: DefinedUseTRPCQueryResult<{
    posts: {
        id: number;
        title: string;
    }[];
}, TRPCClientErrorLike<{
    errorShape: DefaultErrorShape;
    transformer: false;
}>>
allPostQuery
.
data: {
    posts: {
        id: number;
        title: string;
    }[];
}
data
.
posts: {
    id: number;
    title: string;
}[]
posts
.
Array<{ id: number; title: string; }>.map<React.JSX.Element>(callbackfn: (value: {
    id: number;
    title: string;
}, index: number, array: {
    id: number;
    title: string;
}[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
map
((
post: {
    id: number;
    title: string;
}
post
) => (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div React.Attributes.key?: React.Key | null | undefinedkey={
post: {
    id: number;
    title: string;
}
post
.id: numberid}>{
post: {
    id: number;
    title: string;
}
post
.title: stringtitle}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>
))} </React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div> ); }

Helpers

Much like useUtils, createTRPCQueryUtils gives you access to same set of helpers, including queryOptions and infiniteQueryOptions. The only difference is that you need to pass in the queryClient and client objects.

You can see them on the useUtils-page.