HTTP Link / httpLink
httpLink
is a terminating link that sends a tRPC operation to a tRPC procedure over HTTP.
httpLink
supports both POST and GET requests and provides several key capabilities:
- Sending
FormData
for file uploads and form submissions - Handling custom response types like
Response
objects for advanced use cases (file downloads, streams, etc.) - Standard JSON responses for regular API calls
You likely want to combine this link with httpBatchLink
or httpBatchStreamLink
using a by splitLink
to handle different types of operations in your app.
Usage
You can import and add the httpLink
to the links
array as such:
client/index.tsts
import { createTRPCClient, httpLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpLink({url: 'http://localhost:3000',// transformer,}),],});
client/index.tsts
import { createTRPCClient, httpLink } from '@trpc/client';import type { AppRouter } from '../server';const client = createTRPCClient<AppRouter>({links: [httpLink({url: 'http://localhost:3000',// transformer,}),],});
Key Features
FormData
Support
httpLink
allows you to send FormData
directly to your procedures, making it ideal for file uploads and form submissions:
Prerequisites for the example below: Install zod
and zod-form-data
- npm
- yarn
- pnpm
- bun
- deno
npm install zod zod-form-data
yarn add zod zod-form-data
pnpm add zod zod-form-data
bun add zod zod-form-data
deno add npm:zod npm:zod-form-data
ts
import {publicProcedure ,router } from './server';import {processFileStream } from './utils';import {z } from 'zod';import {zfd } from 'zod-form-data';constappRouter =router ({uploadFile :publicProcedure .input (zfd .formData ({file :zfd .file (),})).mutation (async (opts ) => {// ...}),});
ts
import {publicProcedure ,router } from './server';import {processFileStream } from './utils';import {z } from 'zod';import {zfd } from 'zod-form-data';constappRouter =router ({uploadFile :publicProcedure .input (zfd .formData ({file :zfd .file (),})).mutation (async (opts ) => {// ...}),});
client.tsts
const formData = new FormData();formData.append('file', fileInput.files[0]);// Send FormData to your procedureconst result = await client.uploadFile.mutate(formData);
client.tsts
const formData = new FormData();formData.append('file', fileInput.files[0]);// Send FormData to your procedureconst result = await client.uploadFile.mutate(formData);
Custom Response Types
When your server procedures return Response
objects, httpLink
can handle various response types including:
- File downloads
- Streams
- Returning custom content types
- Special headers
ts
// Server procedure returning a custom Responseconst appRouter = t.router({downloadFile: publicProcedure.query(() => {return new Response('Hello World', {headers: {'Content-Type': 'text/plain','Content-Disposition': 'attachment; filename="hello.txt"',},});}),});// Client usageconst response = await client.downloadFile.query();// response is a Response object you can handle accordingly
ts
// Server procedure returning a custom Responseconst appRouter = t.router({downloadFile: publicProcedure.query(() => {return new Response('Hello World', {headers: {'Content-Type': 'text/plain','Content-Disposition': 'attachment; filename="hello.txt"',},});}),});// Client usageconst response = await client.downloadFile.query();// response is a Response object you can handle accordingly
httpLink
Options
The httpLink
function takes an options object that has the HTTPLinkOptions
shape.
ts
export interface HTTPLinkOptions {url: string;/*** Add ponyfill for fetch*/fetch?: typeof fetch;/*** Add ponyfill for AbortController*/AbortController?: typeof AbortController | null;/*** Data transformer* @see https://trpc.io/docs/v11/data-transformers**/transformer?: DataTransformerOptions;/*** Headers to be set on outgoing requests or a callback that of said headers* @see http://trpc.io/docs/v10/header*/headers?:| HTTPHeaders| ((opts: { op: Operation }) => HTTPHeaders | Promise<HTTPHeaders>);/*** Send all requests as POSTS requests regardless of the procedure type* The server must separately allow overriding the method. See:* @see https://trpc.io/docs/rpc*/methodOverride?: 'POST';}
ts
export interface HTTPLinkOptions {url: string;/*** Add ponyfill for fetch*/fetch?: typeof fetch;/*** Add ponyfill for AbortController*/AbortController?: typeof AbortController | null;/*** Data transformer* @see https://trpc.io/docs/v11/data-transformers**/transformer?: DataTransformerOptions;/*** Headers to be set on outgoing requests or a callback that of said headers* @see http://trpc.io/docs/v10/header*/headers?:| HTTPHeaders| ((opts: { op: Operation }) => HTTPHeaders | Promise<HTTPHeaders>);/*** Send all requests as POSTS requests regardless of the procedure type* The server must separately allow overriding the method. See:* @see https://trpc.io/docs/rpc*/methodOverride?: 'POST';}
Reference
You can check out the source code for this link on GitHub.