Set up with Next.js Pages Router
On this page
Recommended file structure
We recommend a file structure like this one, although it is not enforced by tRPC. This is what you'll see in our examples. The rest of this page will take you through the process of adding tRPC in to this structure.
.
├── prisma # <-- if prisma is added
│ └── [..]
├── src
│ ├── pages
│ │ ├── _app.tsx # <-- add `withTRPC()`-HOC here
│ │ ├── api
│ │ │ └── trpc
│ │ │ └── [trpc].ts # <-- tRPC HTTP handler
│ │ └── [..]
│ ├── server
│ │ ├── routers
│ │ │ ├── _app.ts # <-- main app router
│ │ │ ├── post.ts # <-- sub routers
│ │ │ └── [..]
│ │ ├── context.ts # <-- create app context
│ │ └── trpc.ts # <-- procedure helpers
│ └── utils
│ └── trpc.ts # <-- your typesafe tRPC hooks
└── [..]Add tRPC to existing Next.js project
1. Install deps
pnpm add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zodnpm install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zodyarn add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zodbun add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zodThe Next.js integration is actually a combination of our React Query Integration and some Next.js specific integrations.
2. Enable strict mode
If you want to use Zod for input validation, make sure you have enabled strict mode in your tsconfig.json:
"compilerOptions": {
+ "strict": true
}If strict mode is too harsh, you'll at least want to enable strictNullChecks:
"compilerOptions": {
+ "strictNullChecks": true
}3. Create a tRPC router
Initialize your tRPC backend in src/server/trpc.ts using the initTRPC function, and create your first router. We're going to make a simple "hello world" router and procedure here - but for deeper information on creating your tRPC API you should refer to:
- the Quickstart guide and Backend usage docs for tRPC information
- the Next.js Adapter docs for mounting tRPC within your Next.js server.
View sample backend
import { const initTRPC: TRPCBuilder<object, object>initTRPC } from '@trpc/server';
// Avoid exporting the entire t-object
// since it's not very descriptive.
// For instance, the use of a t variable
// is common in i18n libraries.
const const t: TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
t = const initTRPC: TRPCBuilder<object, object>initTRPC.TRPCBuilder<object, object>.create<RuntimeConfigOptions<object, object>>(opts?: RuntimeConfigOptions<object, object> | undefined): TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
create();
// Base router and procedure helpers
export const const router: RouterBuilder<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
router = const t: TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
t.TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, { ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }>.router: RouterBuilder<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
router;
export const const procedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>procedure = const t: TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
t.TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, { ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }>.procedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>procedure;import { import zz } from 'zod';
import { const procedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>procedure, const router: RouterBuilder<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
router } from '../trpc';
export const const appRouter: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>
appRouter = router<{
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>(_: {
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}): BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>
router({
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>
hello: const procedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>procedure
.ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.input<z.ZodObject<{
text: z.ZodString;
}, z.core.$strip>>(schema: z.ZodObject<{
text: z.ZodString;
}, z.core.$strip>): ProcedureBuilder<object, object, object, {
text: string;
}, {
text: string;
}, UnsetMarker, UnsetMarker, false, DefaultErrorShape>
input(
import zz.function object<{
text: z.ZodString;
}>(shape?: {
text: z.ZodString;
} | undefined, params?: string | {
error?: string | z.core.$ZodErrorMap<NonNullable<z.core.$ZodIssueUnrecognizedKeys | z.core.$ZodIssueInvalidType<unknown>>> | undefined;
message?: string | undefined | undefined;
} | undefined): z.ZodObject<{
text: z.ZodString;
}, z.core.$strip>
object({
text: z.ZodStringtext: import zz.function string(params?: string | z.core.$ZodStringParams): z.ZodString (+1 overload)string(),
}),
)
.ProcedureBuilder<object, object, object, { text: string; }, { text: string; }, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.query<{
greeting: string;
}>(resolver: ProcedureResolver<object, object, object, {
text: string;
}, UnsetMarker, {
greeting: string;
}>): QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>
query((opts: ProcedureResolverOptions<object, object, object, {
text: string;
}>
opts) => {
return {
greeting: stringgreeting: `hello ${opts: ProcedureResolverOptions<object, object, object, {
text: string;
}>
opts.ProcedureResolverOptions<object, object, object, { text: string; }>.input: {
text: string;
}
input.text: stringtext}`,
};
}),
});
// export type definition of API
export type type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>> & DecorateCreateRouterOptions<{
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>
AppRouter = typeof const appRouter: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>
appRouter;import * as import trpcNexttrpcNext from '@trpc/server/adapters/next';
import { const appRouter: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>
appRouter } from '../../../server/routers/_app';
// export API handler
// @link https://trpc.io/docs/server/adapters
export default import trpcNexttrpcNext.function createNextApiHandler<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>(opts: NodeHTTPHandlerOptions<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>, trpcNext.NextApiRequest, trpcNext.NextApiResponse>): trpcNext.NextApiHandler
createNextApiHandler({
BaseHandlerOptions<BuiltRouter<{ ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }, DecorateCreateRouterOptions<{}>>, NextApiRequest>.router: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>
router: const appRouter: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>
appRouter,
createContext?: NodeHTTPCreateContextFn<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>, trpcNext.NextApiRequest, trpcNext.NextApiResponse> | undefined
createContext: () => ({}),
});4. Create tRPC hooks
Use the createTRPCNext function to create a set of strongly-typed hooks from your API's type signature.
import { function httpBatchLink<TRouter extends AnyRouter>(opts: HTTPBatchLinkOptions<TRouter["_def"]["_config"]["$types"]>): TRPCLink<TRouter>httpBatchLink } from '@trpc/client';
import { function createTRPCNext<TRouter extends AnyRouter, TSSRContext extends NextPageContext = NextPageContext>(opts: WithTRPCNoSSROptions<TRouter> | WithTRPCSSROptions<TRouter>): CreateTRPCNext<TRouter, TSSRContext>createTRPCNext } from '@trpc/next';
import type { type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>> & DecorateCreateRouterOptions<{}>
AppRouter } from '../server/routers/_app';
function function getBaseUrl(): stringgetBaseUrl() {
if (typeof var window: Window & typeof globalThiswindow !== 'undefined')
// browser should use relative path
return '';
if (var process: NodeJS.Processprocess.NodeJS.Process.env: NodeJS.ProcessEnvenv.string | undefinedVERCEL_URL)
// reference for vercel.com
return `https://${var process: NodeJS.Processprocess.NodeJS.Process.env: NodeJS.ProcessEnvenv.stringVERCEL_URL}`;
if (var process: NodeJS.Processprocess.NodeJS.Process.env: NodeJS.ProcessEnvenv.string | undefinedRENDER_INTERNAL_HOSTNAME)
// reference for render.com
return `http://${var process: NodeJS.Processprocess.NodeJS.Process.env: NodeJS.ProcessEnvenv.stringRENDER_INTERNAL_HOSTNAME}:${var process: NodeJS.Processprocess.NodeJS.Process.env: NodeJS.ProcessEnvenv.string | undefinedPORT}`;
// assume localhost
return `http://localhost:${var process: NodeJS.Processprocess.NodeJS.Process.env: NodeJS.ProcessEnvenv.string | undefinedPORT ?? 3000}`;
}
export const const trpc: CreateTRPCNextBase<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>, NextPageContext> & DecorateRouterRecord<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>
trpc = createTRPCNext<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>, NextPageContext>(opts: WithTRPCNoSSROptions<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>> | WithTRPCSSROptions<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<...>>>): CreateTRPCNextBase<...> & DecorateRouterRecord<...>
createTRPCNext<type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>> & DecorateCreateRouterOptions<{}>
AppRouter>({
config: (info: {
ctx?: NextPageContext;
}) => WithTRPCConfig<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>
config(config: {
ctx?: NextPageContext;
}
config) {
return {
links: TRPCLink<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>[]
links: [
httpBatchLink<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>(opts: HTTPBatchLinkOptions<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>): TRPCLink<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>
httpBatchLink({
/**
* If you want to use SSR, you need to use the server's full URL
* @see https://trpc.io/docs/client/nextjs/pages-router/ssr
**/
url: string | URLurl: `${function getBaseUrl(): stringgetBaseUrl()}/api/trpc`,
// You can pass any HTTP headers you wish here
async headers?: HTTPHeaders | ((opts: {
opList: NonEmptyArray<Operation>;
}) => HTTPHeaders | Promise<HTTPHeaders>) | undefined
headers() {
return {
// authorization: getAuthCookie(),
};
},
}),
],
};
},
/**
* @see https://trpc.io/docs/client/nextjs/pages-router/ssr
**/
ssr: falsessr: false,
});5. Configure _app.tsx
Wrap your root app page in the trpc.withTRPC HOC, similar to this:
import type { type AppType<P = {}> = ComponentType<AppPropsType<any, P>> & {
getInitialProps?(context: AppContextType<NextRouter>): P | Promise<P>;
}
AppType } from 'next/app';
import { const trpc: CreateTRPCNextBase<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>, NextPageContext> & DecorateRouterRecord<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>
trpc } from '../utils/trpc';
const const MyApp: AppTypeMyApp: type AppType<P = {}> = ComponentType<AppPropsType<any, P>> & {
getInitialProps?(context: AppContextType<NextRouter>): P | Promise<P>;
}
AppType = ({ type Component: NextComponentType<NextPageContext, any, any>Component, pageProps: {}pageProps }) => {
return <type Component: NextComponentType<NextPageContext, any, any>Component {...pageProps: {}pageProps} />;
};
export default const trpc: CreateTRPCNextBase<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>, NextPageContext> & DecorateRouterRecord<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>
trpc.CreateTRPCNextBase<BuiltRouter<{ ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }, DecorateCreateRouterOptions<{}>>, NextPageContext>.withTRPC: (AppOrPage: NextComponentType<any, any, any>) => NextComponentTypewithTRPC(const MyApp: FunctionComponent<AppPropsType<any, {}>> & {
getInitialProps?(context: AppContextType<NextRouter>): {} | Promise<{}>;
}
MyApp);6. Make an API request
You're all set!
You can now use the React hooks you have just created to invoke your API. For more detail see the React Query Integration
import { const trpc: CreateTRPCNextBase<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>, NextPageContext> & DecorateRouterRecord<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>
trpc } from '../utils/trpc';
export default function function IndexPage(): JSX.ElementIndexPage() {
const const hello: UseTRPCQueryResult<{
greeting: string;
}, TRPCClientErrorLike<{
input: {
text: string;
};
output: {
greeting: string;
};
transformer: false;
errorShape: DefaultErrorShape;
}>>
hello = const trpc: CreateTRPCNextBase<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>, NextPageContext> & DecorateRouterRecord<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
hello: QueryProcedure<{
input: {
text: string;
};
output: {
greeting: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
}>>
trpc.hello: DecoratedQuery<{
input: {
text: string;
};
output: {
greeting: string;
};
transformer: false;
errorShape: DefaultErrorShape;
}>
hello.useQuery: ProcedureUseQuery
<{
greeting: string;
}, {
greeting: string;
}>(input: {
text: string;
} | unique symbol, opts?: UseTRPCQueryOptions<{
greeting: string;
}, {
greeting: string;
}, TRPCClientErrorLike<{
input: {
text: string;
};
output: {
greeting: string;
};
transformer: false;
errorShape: DefaultErrorShape;
}>, {
greeting: string;
}> | undefined) => UseTRPCQueryResult<{
greeting: string;
}, TRPCClientErrorLike<{
input: {
text: string;
};
output: {
greeting: string;
};
transformer: false;
errorShape: DefaultErrorShape;
}>> (+1 overload)
useQuery({ text: stringtext: 'client' });
if (!const hello: UseTRPCQueryResult<{
greeting: string;
}, TRPCClientErrorLike<{
input: {
text: string;
};
output: {
greeting: string;
};
transformer: false;
errorShape: DefaultErrorShape;
}>>
hello.data: {
greeting: string;
} | undefined
data) {
return <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>Loading...</JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>;
}
return (
<JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>
<JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>p>{const hello: (TRPCHookResult & QueryObserverRefetchErrorResult<{
greeting: string;
}, TRPCClientErrorLike<{
input: {
text: string;
};
output: {
greeting: string;
};
transformer: false;
errorShape: DefaultErrorShape;
}>>) | (TRPCHookResult & QueryObserverSuccessResult<{
greeting: string;
}, TRPCClientErrorLike<{
input: {
text: string;
};
output: {
greeting: string;
};
transformer: false;
errorShape: DefaultErrorShape;
}>>) | (TRPCHookResult & QueryObserverPlaceholderResult<...>)
hello.data: {
greeting: string;
}
data.greeting: stringgreeting}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>p>
</JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>
);
}createTRPCNext() options
config-callback
The config-argument is a function that returns an object that configures the tRPC and React Query clients. This function receives an object with an optional ctx property (of type NextPageContext) that gives you access to the Next.js req object during server-side rendering. The returned value can contain the following properties:
- Required:
linksto customize the flow of data between tRPC Client and the tRPC Server. Read more.- Optional:
queryClientConfig: a configuration object for the React QueryQueryClientused internally by the tRPC React hooks: QueryClient docsqueryClient: a React Query QueryClient instance- Note: You can only provide either a
queryClientor aqueryClientConfig.
- Note: You can only provide either a
transformer: a transformer applied to outgoing payloads. Read more about Data TransformersabortOnUnmount: determines if in-flight requests will be cancelled on component unmount. This defaults tofalse.
overrides: (default: undefined)
Configure overrides for React Query's hooks.
ssr-boolean (default: false)
Whether tRPC should await queries when server-side rendering a page. Defaults to false.
responseMeta-callback
Ability to set request headers and HTTP status when server-side rendering.
Example
import { function createTRPCNext<TRouter extends AnyRouter, TSSRContext extends NextPageContext = NextPageContext>(opts: WithTRPCNoSSROptions<TRouter> | WithTRPCSSROptions<TRouter>): CreateTRPCNext<TRouter, TSSRContext>createTRPCNext } from '@trpc/next';
import type { type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>> & DecorateCreateRouterOptions<{}>
AppRouter } from '../server/routers/_app';
export const const trpc: CreateTRPCNextBase<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>, NextPageContext> & DecorateRouterRecord<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>
trpc = createTRPCNext<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>, NextPageContext>(opts: WithTRPCNoSSROptions<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>> | WithTRPCSSROptions<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<...>>>): CreateTRPCNextBase<...> & DecorateRouterRecord<...>
createTRPCNext<type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>> & DecorateCreateRouterOptions<{}>
AppRouter>({
config: (info: {
ctx?: NextPageContext;
}) => WithTRPCConfig<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>
config(config: {
ctx?: NextPageContext;
}
config) {
return {
links: TRPCLink<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{}>>>[]
links: [
/* [...] */
],
};
},
});Next steps
Browse the rest of the docs to learn more about things like authorization, middlewares, and error handling.
You can also find information about queries and mutations now that you're using @trpc/react-query.