new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

tRPC · all subjects

client/next.js

55 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Per-request abortOnUnmount example

const postQuery = trpc.post.byId.useQuery({ id }, { trpc: { abortOnUnmount: true } });

Global abortOnUnmount example

export const trpc = createTRPCNext<AppRouter>({ config() { return { links: [ httpBatchLink({ url: '/api/trpc', }), ], abortOnUnmount: true, }; }, });

abortOnUnmount global configuration

You can enable request cancellation on unmount globally by setting abortOnUnmount: true in the configuration passed to createTRPCNext.

abortOnUnmount configuration default

By default, tRPC does not cancel requests on unmount.

Dehydrating and passing state to client

Use helpers.dehydrate() to serialize the prefetched query cache. Return it in getServerSideProps or getStaticProps with the key trpcState: { trpcState: helpers.dehydrate() }. This is very important - use trpcState as the key.

Server-side helpers Next.js getServerSideProps example

Example using server-side helpers in getServerSideProps: Create helpers with router, ctx, and transformer. Call helpers.post.byId.prefetch({ id }) to prefetch. Return { props: { trpcState: helpers.dehydrate(), id } } to pass dehydrated state to client.

Server-side helpers inner and outer context pattern

When using internal router with createServerSideHelpers, instantiate with a context that does not include req and res. The documentation recommends using the inner and outer context concept to provide appropriate context to server-side helpers without HTTP request and response objects.

Server-side helpers purpose

Server-side helpers provide helper functions to prefetch queries on the server. Prefetching via server-side helpers populates the query cache on the server, so queries do not have to fetch on the client initially. This is useful for SSG and for SSR when not using ssr: true.

createServerSideHelpers with internal router

When you have direct access to your tRPC router (monolithic Next.js application), instantiate createServerSideHelpers with the router, ctx, and transformer parameters. The context should not include req and res; use inner and outer context pattern instead. Example: createServerSideHelpers({ router: appRouter, ctx: await createContext(), transformer: superjson })

createServerSideHelpers with external router

When you don't have direct access to your tRPC router (Next.js application with standalone API), create a tRPC client first using createTRPCClient with httpBatchLink, then pass it to createServerSideHelpers with the client parameter. Example: createServerSideHelpers({ client: proxyClient })

Server-side helpers methods

The server-side helpers return an object mirroring your router structure. Instead of useQuery and useMutation, you get: prefetch, fetch, prefetchInfinite, and fetchInfinite functions. These are wrappers around react-query functions.

Difference between prefetch and fetch

prefetch does not return the result and never throws. It adds the query to the cache for dehydration and client-side sending. fetch acts like a normal function call, returning the result and throwing errors. Use prefetch for queries needed on the client, and fetch for queries where you need the result on the server.

createServerSideHelpers configuration

createServerSideHelpers is called with an object containing: router (the appRouter), ctx (context object, can be empty), and transformer (optional, e.g., superjson for serialization). It returns a helpers object with methods matching the router structure that can be used to prefetch queries.

Dehydrating queries in SSG

After prefetching queries with helpers, call helpers.dehydrate() to serialize the cached query data. Return this as trpcState in the props object from getStaticProps. The client-side trpc instance will automatically hydrate this state.

React Query refetch behavior in SSG

React Query by default refetches data on client-side mount and window focus. When using getStaticProps with prefetched data, set refetchOnMount: false and refetchOnWindowFocus: false in query options to prevent unnecessary refetches if you want to only use the server-generated data.

Per-query refetch configuration

Disable refetching on a single query by passing query options as the second argument to useQuery: trpc.post.byId.useQuery({ id }, { refetchOnMount: false, refetchOnWindowFocus: false }). If the query takes no input, pass undefined as the first argument to avoid accidentally passing options as the input.

Global refetch configuration in createTRPCNext

Configure refetch behavior globally by setting queryClientConfig.defaultOptions.queries in the trpc instance config. Pass an object with refetchOnMount: false and refetchOnWindowFocus: false to disable refetching for all queries by default across the application.

getStaticPaths with revalidate for ISR

Use getStaticPaths to determine which dynamic pages should be pre-rendered. With getStaticProps, set revalidate to a number (in seconds) to enable Incremental Static Regeneration (ISR), allowing pages to be revalidated at intervals. Use fallback: 'blocking' to generate missing pages on-demand.

Caution: mixed static and dynamic queries

Be careful when applying global refetch configuration if your app has a mixture of static and dynamic queries. Disabling refetching globally may cause dynamic queries to not refresh when needed. Consider using per-query configuration instead.

SSG with getStaticProps and server-side helpers

Static site generation in Next.js pages router requires executing tRPC queries inside getStaticProps. Use createServerSideHelpers to prefetch queries, dehydrate them, and pass trpcState to the page. The queries will automatically pick up the trpcState and use it as an initial value.

Create tRPC Next.js client with createTRPCNext

Use createTRPCNext function in utils/trpc.ts to create strongly-typed hooks from the AppRouter type. Pass a config object with: required links array (configure data flow), and optional queryClientConfig, queryClient, transformer, and abortOnUnmount properties. The config function receives an optional ctx object containing Next.js req during SSR.

createTRPCNext config options

The createTRPCNext function accepts a config object with the following properties: - config (required): Function returning object with links (required array) and optional queryClientConfig, queryClient, transformer, abortOnUnmount properties - overrides (optional): Configure overrides for React Query hooks - ssr (optional, default false): Whether to await queries during server-side rendering - responseMeta (optional): Callback to set request headers and HTTP status during SSR

queryClient vs queryClientConfig in createTRPCNext

In createTRPCNext config, you can provide either a queryClient (React Query QueryClient instance) or a queryClientConfig (configuration object for QueryClient), but not both.

abortOnUnmount default behavior

The abortOnUnmount option in createTRPCNext determines if in-flight requests are cancelled on component unmount. It defaults to false.

getBaseUrl helper for SSR

When using SSR in tRPC with Next.js, use a getBaseUrl helper function that: returns empty string in browser (relative path), returns https://{process.env.VERCEL_URL} for Vercel, returns http://{process.env.RENDER_INTERNAL_HOSTNAME}:{process.env.PORT} for Render.com, and falls back to http://localhost:{PORT or 3000}.

Recommended file structure for Next.js Pages Router

The recommended tRPC file structure for Next.js Pages Router projects is: prisma directory at root, src/pages containing _app.tsx with withTRPC() HOC and api/trpc/[trpc].ts HTTP handler, src/server containing routers/_app.ts (main router), sub-routers in routers/ directory, context.ts for app context, and trpc.ts for procedure helpers, src/utils containing trpc.ts for typesafe hooks, and additional files at root level. This structure is used in tRPC examples but is not enforced.

createTRPCNext does not work with tRPC v9 interop mode

The createTRPCNext function does not work with tRPC v9 interop mode. If migrating from v9 using interop, continue using the old way of initializing tRPC for Next.js.

Required packages for Next.js Pages Router setup

To set up tRPC with Next.js Pages Router, install: @trpc/server, @trpc/client, @trpc/react-query, @trpc/next, @tanstack/react-query (latest), and zod.

TypeScript strict mode for Zod validation

To use Zod for input validation in tRPC, enable strict mode in tsconfig.json by setting compilerOptions.strict to true. If strict mode is too restrictive, at minimum enable strictNullChecks.

Initialize tRPC backend with initTRPC

Initialize the tRPC backend in src/server/trpc.ts using the initTRPC function. Call initTRPC.create() to create a t object, then export router and procedure helpers from it. The t variable name is not recommended for export since it is not descriptive.

Example: Basic tRPC backend with hello procedure

Example of server/trpc.ts: ```ts import { initTRPC } from '@trpc/server'; const t = initTRPC.create(); export const router = t.router; export const procedure = t.procedure; ``` Example of server/routers/_app.ts: ```ts import { z } from 'zod'; import { procedure, router } from '../trpc'; export const appRouter = router({ hello: procedure .input( z.object({ text: z.string(), }), ) .query((opts) => { return { greeting: `hello ${opts.input.text}`, }; }), }); export type AppRouter = typeof appRouter; ```

Example: Using tRPC hooks in a page component

Example of pages/index.tsx using tRPC query: ```tsx import { trpc } from '../utils/trpc'; export default function IndexPage() { const hello = trpc.hello.useQuery({ text: 'client' }); if (!hello.data) { return <div>Loading...</div>; } return ( <div> <p>{hello.data.greeting}</p> </div> ); } ```

Wrap app with trpc.withTRPC HOC

In pages/_app.tsx, wrap the root app component with the trpc.withTRPC higher-order component. Example: ```tsx import type { AppType } from 'next/app'; import { trpc } from '../utils/trpc'; const MyApp: AppType = ({ Component, pageProps }) => { return <Component {...pageProps} />; }; export default trpc.withTRPC(MyApp); ```

Example: createTRPCNext client setup

Example of utils/trpc.ts: ```ts import { httpBatchLink } from '@trpc/client'; import { createTRPCNext } from '@trpc/next'; import type { AppRouter } from '../server/routers/_app'; function getBaseUrl() { if (typeof window !== 'undefined') return ''; if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`; if (process.env.RENDER_INTERNAL_HOSTNAME) return `http://${process.env.RENDER_INTERNAL_HOSTNAME}:${process.env.PORT}`; return `http://localhost:${process.env.PORT ?? 3000}`; } export const trpc = createTRPCNext<AppRouter>({ config(config) { return { links: [ httpBatchLink({ url: `${getBaseUrl()}/api/trpc`, async headers() { return {}; }, }), ], }; }, ssr: false, }); ```

SSR response caching example with stale-while-revalidate

Example cache header for SSR: `s-maxage=1, stale-while-revalidate=86400` caches for 1 day and revalidates once per second. Include this in the headers returned by `responseMeta`.

Enable SSR with createTRPCNext

To enable Server-Side Rendering in tRPC with Next.js pages router, set `ssr: true` in the `createTRPCNext` config callback.

SSR uses getInitialProps for query prefetching

When SSR is enabled, tRPC uses `getInitialProps` to prefetch all queries on the server. This can cause problems when used together with `getServerSideProps`.

Conditional SSR with callback

The `ssr` option in `createTRPCNext` can accept a callback function that receives options and returns a boolean or a Promise resolving to a boolean, allowing you to conditionally enable SSR based on request properties.

Forward client headers during SSR

When using SSR, you must manually forward client headers like cookies from the request to the server. This is done in the `config` callback by checking `ctx?.req?.headers` and returning them in the `httpBatchLink` headers function.

Alternative to SSR: Server-Side Helpers

Instead of enabling SSR, you can leave it disabled (the default) and use Server-Side Helpers to prefetch queries in `getStaticProps` or `getServerSideProps`.

Use ssrPrepass helper for SSR

The `ssrPrepass` helper from `@trpc/next/ssrPrepass` should be included in the `createTRPCNext` config when enabling SSR to properly handle server-side query execution.

SSR with httpBatchLink configuration example

When configuring SSR, use `httpBatchLink` with the full URL on the server side (obtained from `getBaseUrl()`) and the relative `/api/trpc` URL on the client side. The config callback receives `info.ctx` which contains the request object.

responseMeta for SSR response caching

The `responseMeta` callback on `createTRPCNext` can set cache headers for SSR responses. It receives options containing `clientErrors` and should return an object with optional `status` and `headers` properties.

Connection header forbidden in Node 18 SSR

When using SSR on Node 18, the `connection` header must be removed from forwarded headers because it is a forbidden header name and will cause data fetching to fail with a `TRPCClientError: fetch failed` error.

React Query refetching with SSR initial data

By default, @tanstack/react-query refetches data on mount and window refocus even when initial data is provided via SSR. This ensures data is always up-to-date but results in additional network requests visible in the Network tab.

Disable refetching behavior with SSG

To prevent React Query from refetching data after SSR, refer to the SSG (Static Site Generation) page for configuration options that disable this default refetch behavior.

Next.js Pages Router Prisma starter example

A Next.js starter project with Prisma, E2E testing, and ESLint for the Pages Router. The live demo is at https://nextjs.trpc.io. Can be cloned with: yarn create next-app --example https://github.com/trpc/trpc --example-path examples/next-prisma-starter trpc-prisma-starter

zART-stack monorepo example

A starter project demonstrating the zART-stack (zero-API, TypeScript, React) with a monorepo setup including React Native, Next.js, and Prisma for the Pages Router. Can be cloned with: git clone git@github.com:KATT/zart.git. Source: https://github.com/KATT/zART

Next.js TodoMVC Prisma example

A Next.js Pages Router example demonstrating static site generation (SSG) with Prisma using a TodoMVC-style application. The live demo is at https://todomvc.trpc.io. Can be cloned with: yarn create next-app --example https://github.com/trpc/trpc --example-path examples/next-prisma-todomvc trpc-todo

Next.js /pages directory has dedicated integration

If using Next.js with the /pages directory, tRPC provides a Next.js integration that adds helpers for Server-side Rendering and Static Generation.

@trpc/next SSR mode requires prepass helper

In v11, @trpc/next SSR mode now requires a prepass helper with ssr: true configuration. This change was made to avoid importing react-dom when SSR functionality is not being used.

Set up tRPC hooks with createTRPCNext

Use createTRPCNext from @trpc/next with the AppRouter type. Return a config object with links containing httpBatchLink. The getBaseUrl() function should return empty string if window is defined, else check process.env.VERCEL_URL, else return http://localhost with PORT. Set ssr: false for basic setup.

Wrap Next.js Pages Router app with withTRPC HOC

In pages/_app.tsx, import trpc from utils and export default trpc.withTRPC(MyApp) where MyApp accepts Component and pageProps.

Use tRPC hooks in Pages Router pages

Import trpc from utils/trpc and call hooks like trpc.hello.useQuery({ text: 'client' }) directly in page components.

Get base URL for tRPC client in Next.js

The getBaseUrl() function returns empty string if window is defined (client-side), else checks process.env.VERCEL_URL for production and returns https://VERCEL_URL, else returns http://localhost:PORT where PORT defaults to 3000.

Give your agent this brain