Set up a tRPC Client
On this page
1. Install the tRPC Client library
Use your preferred package manager to install the @trpc/client library, and also install @trpc/server which contains some required types.
pnpm add @trpc/server @trpc/clientnpm install @trpc/server @trpc/clientyarn add @trpc/server @trpc/clientbun add @trpc/server @trpc/client2. Import your App Router
Import your AppRouter type into the client application. This type holds the shape of your entire API.
utils/trpc.ts
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<{
byId: QueryProcedure<{
input: {
id: string;
};
output: {
id: string;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>;
}>> & DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
byId: QueryProcedure<{
input: {
id: string;
};
output: {
id: string;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>;
}>
AppRouter } from '../server/router';3. Initialize the tRPC client
Create a tRPC client with the createTRPCClient method, and add a links array with a terminating link pointing at your API. To learn more about tRPC links, click here.
client.ts
import { function createTRPCClient<TRouter extends AnyRouter>(opts: CreateTRPCClientOptions<TRouter>): TRPCClient<TRouter>createTRPCClient, function httpBatchLink<TRouter extends AnyRouter>(opts: HTTPBatchLinkOptions<TRouter["_def"]["_config"]["$types"]>): TRPCLink<TRouter>httpBatchLink } from '@trpc/client';
import type { type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>> & DecorateCreateRouterOptions<{}>
AppRouter } from './server';
const const client: TRPCClient<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>
client = createTRPCClient<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>(opts: CreateTRPCClientOptions<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>): TRPCClient<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<...>>>
createTRPCClient<type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>> & DecorateCreateRouterOptions<{}>
AppRouter>({
links: TRPCLink<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>[]
links: [
httpBatchLink<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>(opts: HTTPBatchLinkOptions<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>): TRPCLink<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>
httpBatchLink({
url: string | URLurl: 'http://localhost:3000/trpc',
// You can pass any HTTP headers you wish here
async headers?: HTTPHeaders | ((opts: {
opList: NonEmptyArray<Operation>;
}) => HTTPHeaders | Promise<HTTPHeaders>) | undefined
headers() {
return {
authorization: stringauthorization: function getAuthCookie(): stringgetAuthCookie(),
};
},
}),
],
});4. Use the tRPC Client
Under the hood this creates a typed JavaScript Proxy which allows you to interact with your tRPC API in a fully type-safe way:
client.ts
const const bilbo: {
id: string;
name: string;
}
bilbo = await const client: TRPCClient<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
getUser: QueryProcedure<{
input: string;
output: {
id: string;
name: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
createUser: MutationProcedure<{
input: {
name: string;
};
output: {
name: string;
id: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>>
client.getUser: {
query: Resolver<{
input: string;
output: {
id: string;
name: string;
};
errorShape: DefaultErrorShape;
transformer: false;
}>;
}
getUser.query: (input: string, opts?: TRPCProcedureOptions) => TRPCTaggedPromise<{
id: string;
name: string;
}, DefaultErrorShape>
query('id_bilbo');
// => { id: 'id_bilbo', name: 'Bilbo' };
const const frodo: {
name: string;
id: string;
}
frodo = await const client: TRPCClient<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
getUser: QueryProcedure<{
input: string;
output: {
id: string;
name: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
createUser: MutationProcedure<{
input: {
name: string;
};
output: {
name: string;
id: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>>
client.createUser: {
mutate: Resolver<{
input: {
name: string;
};
output: {
name: string;
id: string;
};
errorShape: DefaultErrorShape;
transformer: false;
}>;
}
createUser.mutate: (input: {
name: string;
}, opts?: TRPCProcedureOptions) => TRPCTaggedPromise<{
name: string;
id: string;
}, DefaultErrorShape>
mutate({ name: stringname: 'Frodo' });
// => { id: 'id_frodo', name: 'Frodo' };You're all set!