Getting started
1 Install the trpc-sveltekit package and its dependencies with:
pnpm
npm
yarn
bun
pnpm add trpc-sveltekit @trpc/server @trpc/clienttrpc-sveltekit v4 requires @trpc/server and @trpc/client v11 and works with SvelteKit 2 and 3. If you're coming from v3, have a look at the upgrade guide.
2 Create your tRPC router:
lib/trpc/router.ts
import type { Context } from '#lib/trpc/context.ts';
import { initTRPC } from '@trpc/server';
import { setTimeout as delay } from 'node:timers/promises';
export const t = initTRPC.context<Context>().create();
export const router = t.router({
greeting: t.procedure.query(async () => {
await delay(500); // 👈 simulate an expensive operation
return `Hello tRPC v11 @ ${new Date().toLocaleTimeString()}`;
})
});
export const createCaller = t.createCallerFactory(router);
export type Router = typeof router;
3 Create a tRPC context:
lib/trpc/context.ts
import type { RequestEvent } from '@sveltejs/kit';
export async function createContext(event: RequestEvent) {
return {
event // 👈 `event` is now available in your context
};
}
export type Context = Awaited<ReturnType<typeof createContext>>;
4 Add this handle to your SvelteKit app hooks:
hooks.server.ts
import { createContext } from '#lib/trpc/context.ts';
import { router } from '#lib/trpc/router.ts';
import { createTRPCHandle } from 'trpc-sveltekit';
export const handle = createTRPCHandle({ router, createContext });
If you have your own logic to place in the server hook, have a look at the sequence helper function in the SvelteKit docs.
5 Define a helper function to easily use the tRPC client in your pages:
lib/trpc/client.ts
import type { Router } from '#lib/trpc/router.ts';
import { createTRPCClient, type TRPCClientInit } from 'trpc-sveltekit';
type TRPCClient = ReturnType<typeof createTRPCClient<Router>>;
let browserClient: TRPCClient;
export function trpc(init?: TRPCClientInit): TRPCClient {
const isBrowser = typeof window !== 'undefined';
if (isBrowser && browserClient) return browserClient;
const client = createTRPCClient<Router>({ init });
if (isBrowser) browserClient = client;
return client;
}
6 Call the tRPC procedures in your pages:
routes/+page.svelte
<script lang="ts">
import { page } from '$app/state';
import { trpc } from '#lib/trpc/client.ts';
let greeting = $state('press the button to load data');
let loading = $state(false);
const loadData = async (e: MouseEvent) => {
e.preventDefault();
loading = true;
greeting = await trpc(page).greeting.query();
loading = false;
};
</script>
<h6>Loading data in<br /><code>+page.svelte</code></h6>
<a href="#load" role="button" class="secondary" aria-busy={loading} onclick={loadData}>Load</a>
<p>{greeting}</p>
Remember
The trpc-sveltekit package exports two functions: createTRPCHandle and createTRPCClient.
The former is used in your SvelteKit app hooks, the latter is used in your pages.