Skip to content

tRPC integration

The Netlify SDK offers an integration with tRPC, a popular, community-maintained solution for writing queries that offer end-to-end type safety.

tRPC setup files

By default, extensions created by running npm create @netlify/sdk@latest include all of the boilerplate necessary to write tRPC procedures.

  1. The src/server/trpc.ts file exports a few utilities that are used to build the tRPC router and procedures:

    src/server/trpc.ts
    import { initTRPC, TRPCError } from "@trpc/server";
    import { type Context } from "@netlify/sdk/ui/functions/trpc";
    const trpc = initTRPC.context<Context>().create();
    export const router = trpc.router;
    export const procedure = trpc.procedure;

    You shouldn’t have to modify this file frequently. You can, however, define reusable procedures here.

  2. The src/server/router.ts file is where you add your tRPC procedures:

    src/server/router.ts
    import { initTRPC, TRPCError } from "@trpc/server";
    import { type Context } from "@netlify/sdk/ui/functions/trpc";
    import { router } from "./trpc.js";
    export type AppRouter = typeof appRouter;
    export const appRouter = router({
    // Add your tRPC procedures here
    });

    Most of your modifications will be made to this file.

  3. The src/endpoints/trpc.ts file initializes an endpoint that serves the tRPC router:

    src/endpoints/trpc.ts
    import { type Config } from "@netlify/functions";
    import { createNetlifyTRPCHandler } from "@netlify/sdk/ui/functions/trpc";
    import { appRouter } from "../server/router.js";
    export const config: Config = {
    path: ["/api/trpc{/*}?"],
    };
    export default createNetlifyTRPCHandler({
    endpoint: "/api/trpc",
    router: appRouter,
    });

    You shouldn’t have to modify this file frequently, either.

  4. If you’re building extension UI, the src/ui/trpc.ts file initializes a tRPC client compatible with React:

    src/ui/trpc.ts
    import { createTRPCReact } from "@trpc/react-query";
    import type { AppRouter } from "../server/router.js";
    export const trpc = createTRPCReact<AppRouter>();

    This client is used in src/ui/App.tsx to make tRPC client available to the rest of your extension UI app:

    src/ui/App.tsx
    import { httpBatchLink } from "@trpc/client";
    import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
    import { Surfaces, useNetlifyExtensionUIFetch } from "@netlify/sdk/ui/react";
    import { SurfaceRouter, SurfaceRoute } from "@netlify/sdk/ui/react/components";
    import { useState } from "react";
    import { TeamConfiguration } from "./surfaces/TeamConfiguration.jsx";
    import { trpc } from "./trpc.js";
    export const App = () => {
    const fetch = useNetlifyExtensionUIFetch();
    const [queryClient] = useState(() => new QueryClient());
    const [trpcClient] = useState(() =>
    trpc.createClient({
    links: [
    httpBatchLink({ fetch, url: "/api/trpc" }),
    ],
    }),
    );
    return (
    <trpc.Provider client={trpcClient} queryClient={queryClient}>
    <QueryClientProvider client={queryClient}>
    <SurfaceRouter>
    <SurfaceRoute surface={Surfaces.TeamConfiguration}>
    <TeamConfiguration />
    </SurfaceRoute>
    </SurfaceRouter>
    </QueryClientProvider>
    </trpc.Provider>
    );
    };

Next steps

For more information on building tRPC procedures (including queries and mutations), refer to the tRPC documentation.

For more information on how to call tRPC endpoints from extension UI, refer to the extension UI endpoints documentation.

Got it!

Your feedback helps us improve our docs.