Shipkit
DocsFeaturesPricing
DocsFeaturesPricing

Shipkit DocumentationBuild memory optimizationDevelopment GuideEnvironment VariablesError HandlingFile StructureMiddlewareRebranding Guide

Vercel Deployment Checks

Development GuideCLIDependency UpdatesDevToolsFeature FlagsAI PromptsSetup RequirementsSupply chaintRPCWeb Workers

FeaturesAIAnalytics IntegrationAuthenticationCMSDatabaseEmailHapticsPaymentsComponent RegistryStorageUIVisual BuilderWaitlist Feature

Quick StartDeploymentEnvironment VariablesFile StructureSetup Wizard

Caching & Rate LimitingContent ManagementError HandlingMarkdown and MDXMiddlewareProxy-Safe Server ActionsRebranding GuideWebhook Security Implementation GuideMulti-Zone ArchitectureVercel Deployment

IntegrationsPayload CMSDataFast Analytics IntegrationGoogle Analytics IntegrationGoogle Tag Manager IntegrationPostHogStatSig IntegrationUmami Analytics IntegrationAuth.js IntegrationBetter AuthClerkStack Auth IntegrationSupabase Authentication IntegrationBuilder.io IntegrationPayload CMS IntegrationAWS S3 IntegrationResend Email IntegrationUpstash Redis IntegrationVercel Blob IntegrationLemon SqueezyPolarStripe

API RoutesComponentsAPI Route SnippetsAuthentication SnippetsComponent SnippetsForm Handling SnippetsSnippets Introduction

    tRPC

    Shipkit includes a tRPC setup for type-safe API calls between client and server. It's wired up as a demo but ready for production use.

    Structure

    src/lib/trpc/
    ├── api/
    │   ├── root.ts          # App router (registers all sub-routers)
    │   ├── trpc.ts          # Context, middleware, procedure helpers
    │   └── routers/
    │       └── post.ts      # Example router
    ├── react.tsx            # React Query + tRPC client provider
    ├── query-client.ts      # Shared QueryClient config
    └── server.ts            # Server-side caller
    

    Adding a Router

    1. Create a file in src/lib/trpc/api/routers/:
    import { z } from "zod";
    import { createTRPCRouter, publicProcedure, protectedProcedure } from "@/lib/trpc/api/trpc";
    
    export const myRouter = createTRPCRouter({
      list: publicProcedure.query(async ({ ctx }) => {
        return ctx.db.query.myTable.findMany();
      }),
    
      create: protectedProcedure
        .input(z.object({ name: z.string() }))
        .mutation(async ({ ctx, input }) => {
          // ctx.session.user is guaranteed here
          await ctx.db.insert(myTable).values({ name: input.name });
        }),
    });
    
    1. Register it in src/lib/trpc/api/root.ts:
    import { myRouter } from "./routers/my-router";
    
    export const appRouter = createTRPCRouter({
      post: postRouter,
      my: myRouter,
    });
    

    Client Usage

    "use client";
    import { api } from "@/lib/trpc/react";
    
    export function MyComponent() {
      const { data } = api.my.list.useQuery();
      const create = api.my.create.useMutation();
    
      return <button onClick={() => create.mutate({ name: "test" })}>Create</button>;
    }
    

    Server Usage

    import { createCaller } from "@/lib/trpc/api/root";
    
    const trpc = createCaller(createContext);
    const items = await trpc.my.list();
    

    Procedures

    TypeImportAuth required
    publicProcedure@/lib/trpc/api/trpcNo
    protectedProcedure@/lib/trpc/api/trpcYes — ctx.session guaranteed

    Demo Route

    The tRPC demo page lives at /trpc (src/app/(app)/(demo)/trpc/page.tsx).