Use tRPC with SvelteKit and Tanstack Query (full SSR support)
Type-safe svelte(kit) tRPC integration with @tanstack/svelte-query
- Installation
- Basic Example
- SSR Example
- Migrating from v2
``bash`
pnpm i trpc-svelte-query @tanstack/svelte-query
Set up tRPC in lib/trpc/index.ts
`ts
// Import the router type from your server file
import type { AppRouter } from '$lib/server/routes/_app';
import { createTRPCSvelte, httpBatchLink } from 'trpc-svelte-query';
export const trpc = createTRPCSvelte
links: [
httpBatchLink({
url: '/api/trpc',
}),
],
});
`
Set up @tanstack/svelte-query's provider in your root layout.
`svelte
{@render children?.()}
`
Set up your API handler in routes/api/trpc/[...trpc]/+server.ts
`ts
import { appRouter } from '$lib/server/routes/_app';
import { createTRPCSvelteServer } from 'trpc-svelte-query/server';
const trpcServer = createTRPCSvelteServer({
endpoint: '/api/trpc',
router: appRouter,
});
export const GET = trpcServer.handler;
export const POST = trpcServer.handler;
`
Now in any component, you can query your API using the client you created.
`svelte
{#if $query.isSuccess}
{$query.data.greeting}
{$query.error.message}
Loading...
SSR with SvelteKit
Extract your
trpcServer instance into its own file (i.e. $lib/server/server). You'll use this object to handle SSR.`ts
import { appRouter } from '$lib/server/routes/_app';
import { createTRPCSvelteServer } from 'trpc-svelte-query/server';export const trpcServer = createTRPCSvelteServer({
endpoint: '/api/trpc',
router: appRouter,
});
`Use that instance in your api endpoint:
`ts
import { trpcServer } from '$lib/server/server';export const GET = trpcServer.handler;
export const POST = trpcServer.handler;
`Add a root
+layout.server.ts to pass SSR data from the server to the client.`ts
import { trpcServer } from '$lib/server/server';export const load = async (event) => {
return {
trpc: trpcServer.hydrateToClient(event),
};
};
`Update your root layout to hydrate that SSR data.
`svelte
{@render children?.()}
`Add a
+page.server.ts file to preload specific queries.`ts
import { trpc } from '$lib/server/server';export const load = async () => {
await trpcServer.greeting.ssr({ name: 'tRPC' });
};
`Migrating from v2
- Update tRPC to
v11 (migration guide)
- Update SvelteKit to at least 2.20.0
- Remove QueryClientProvider if using SSR:`diff
+layout.svelte:-
{@render children?.()}
-
`- Don't pass
event into SSR functions:`diff
import { trpc } from '$lib/server/server';export const load = async () => {
- await trpcServer.greeting.ssr({ name: 'tRPC' }, event);
+ await trpcServer.greeting.ssr({ name: 'tRPC' });
};
``