在 Next.js Pages Router 中配置 tRPC
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
本指南适用于 Next.js Pages Router。若您使用 Next.js App Router,请参阅 App Router 配置指南。
推荐文件结构
我们推荐采用如下文件结构,尽管 tRPC 并不强制要求。这正是示例项目中采用的结构,本文后续内容将逐步指导你如何在该结构中集成 tRPC。
graphql.├── 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└── [..]
graphql.├── 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└── [..]
在现有 Next.js 项目中集成 tRPC
1. 安装依赖
- npm
- yarn
- pnpm
- bun
- deno
npm install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zod
yarn add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zod
pnpm add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zod
bun add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zod
deno add npm:@trpc/server npm:@trpc/client npm:@trpc/react-query npm:@trpc/next npm:@tanstack/react-query@latest npm:zod
若您使用 AI 编程代理,请安装 tRPC 技能以优化代码生成效果:
bashnpx @tanstack/intent@latest install
bashnpx @tanstack/intent@latest install
Next.js 集成方案本质上是 React Query 集成与 Next.js 特定功能的组合实现。
2. 启用严格模式
若使用 Zod 进行输入验证,需在 tsconfig.json 中启用严格模式:
tsconfig.jsondiff"compilerOptions": {+ "strict": true}
tsconfig.jsondiff"compilerOptions": {+ "strict": true}
如果严格模式限制过强,你至少需要启用 strictNullChecks:
tsconfig.jsondiff"compilerOptions": {+ "strictNullChecks": true}
tsconfig.jsondiff"compilerOptions": {+ "strictNullChecks": true}
3. 创建 tRPC 路由
在 src/server/trpc.ts 中使用 initTRPC 函数初始化 tRPC 后端,并创建你的第一个路由器。我们将在此创建一个简单的 "hello world" 路由器和过程 - 关于创建 tRPC API 的深入信息,请参考:
-
关于在 Next.js 服务器中挂载 tRPC 的 Next.js 适配器文档
View sample backend
server/trpc.tstsimport {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.constt =initTRPC .create ();// Base router and procedure helpersexport constrouter =t .router ;export constprocedure =t .procedure ;
server/trpc.tstsimport {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.constt =initTRPC .create ();// Base router and procedure helpersexport constrouter =t .router ;export constprocedure =t .procedure ;
server/routers/_app.tstsimport {z } from 'zod';import {procedure ,router } from '../trpc';export constappRouter =router ({hello :procedure .input (z .object ({text :z .string (),}),).query ((opts ) => {return {greeting : `hello ${opts .input .text }`,};}),});// export type definition of APIexport typeAppRouter = typeofappRouter ;
server/routers/_app.tstsimport {z } from 'zod';import {procedure ,router } from '../trpc';export constappRouter =router ({hello :procedure .input (z .object ({text :z .string (),}),).query ((opts ) => {return {greeting : `hello ${opts .input .text }`,};}),});// export type definition of APIexport typeAppRouter = typeofappRouter ;
pages/api/trpc/[trpc].tstsimport * astrpcNext from '@trpc/server/adapters/next';import {appRouter } from '../../../server/routers/_app';// export API handler// @link https://trpc.io/docs/server/adaptersexport defaulttrpcNext .createNextApiHandler ({router :appRouter ,createContext : () => ({}),});
pages/api/trpc/[trpc].tstsimport * astrpcNext from '@trpc/server/adapters/next';import {appRouter } from '../../../server/routers/_app';// export API handler// @link https://trpc.io/docs/server/adaptersexport defaulttrpcNext .createNextApiHandler ({router :appRouter ,createContext : () => ({}),});
4. 创建 tRPC 钩子
使用 createTRPCNext 函数,根据 API 类型签名创建强类型的 React Hook 集合。
utils/trpc.tstsximport {httpBatchLink } from '@trpc/client';import {createTRPCNext } from '@trpc/next';import type {AppRouter } from '../server/routers/_app';functiongetBaseUrl () {if (typeofwindow !== 'undefined')// browser should use relative pathreturn '';if (process .env .VERCEL_URL )// reference for vercel.comreturn `https://${process .env .VERCEL_URL }`;if (process .env .RENDER_INTERNAL_HOSTNAME )// reference for render.comreturn `http://${process .env .RENDER_INTERNAL_HOSTNAME }:${process .env .PORT }`;// assume localhostreturn `http://localhost:${process .env .PORT ?? 3000}`;}export consttrpc =createTRPCNext <AppRouter >({config (config ) {return {links : [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 : `${getBaseUrl ()}/api/trpc`,// You can pass any HTTP headers you wish hereasyncheaders () {return {// authorization: getAuthCookie(),};},}),],};},/*** @see https://trpc.io/docs/client/nextjs/pages-router/ssr**/ssr : false,});
utils/trpc.tstsximport {httpBatchLink } from '@trpc/client';import {createTRPCNext } from '@trpc/next';import type {AppRouter } from '../server/routers/_app';functiongetBaseUrl () {if (typeofwindow !== 'undefined')// browser should use relative pathreturn '';if (process .env .VERCEL_URL )// reference for vercel.comreturn `https://${process .env .VERCEL_URL }`;if (process .env .RENDER_INTERNAL_HOSTNAME )// reference for render.comreturn `http://${process .env .RENDER_INTERNAL_HOSTNAME }:${process .env .PORT }`;// assume localhostreturn `http://localhost:${process .env .PORT ?? 3000}`;}export consttrpc =createTRPCNext <AppRouter >({config (config ) {return {links : [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 : `${getBaseUrl ()}/api/trpc`,// You can pass any HTTP headers you wish hereasyncheaders () {return {// authorization: getAuthCookie(),};},}),],};},/*** @see https://trpc.io/docs/client/nextjs/pages-router/ssr**/ssr : false,});
createTRPCNext 不兼容 tRPC v9 的互操作模式。若您正从 v9 迁移且使用互操作功能,请继续采用 旧版初始化方式。
5. 配置 _app.tsx
将根应用页面包裹在 trpc.withTRPC 高阶组件中,类似如下:
pages/_app.tsxtsximport type {AppType } from 'next/app';import {trpc } from '../utils/trpc';constMyApp :AppType = ({Component ,pageProps }) => {return <Component {...pageProps } />;};export defaulttrpc .withTRPC (MyApp );
pages/_app.tsxtsximport type {AppType } from 'next/app';import {trpc } from '../utils/trpc';constMyApp :AppType = ({Component ,pageProps }) => {return <Component {...pageProps } />;};export defaulttrpc .withTRPC (MyApp );
6. 发起 API 请求
全部设置完成!
您现在可以使用刚创建的 React Hook 调用 API 接口。更多细节请参阅 React Query 集成文档。
pages/index.tsxtsximport {trpc } from '../utils/trpc';export default functionIndexPage () {consthello =trpc .hello .useQuery ({text : 'client' });if (!hello .data ) {return <div >Loading...</div >;}return (<div ><p >{hello .data .greeting }</p ></div >);}
pages/index.tsxtsximport {trpc } from '../utils/trpc';export default functionIndexPage () {consthello =trpc .hello .useQuery ({text : 'client' });if (!hello .data ) {return <div >Loading...</div >;}return (<div ><p >{hello .data .greeting }</p ></div >);}
createTRPCNext() 的选项
config 回调函数
config 参数是一个返回配置对象的函数,该对象用于设置 tRPC 和 React Query 客户端。此函数接收包含可选 ctx 属性(类型为 NextPageContext)的对象,使您能在服务端渲染期间访问 Next.js 的 req 对象。返回值可包含以下属性:
-
必需:
-
links:用于定制 tRPC 客户端与服务器间的数据流。了解更多 -
可选:
-
queryClientConfig:用于配置 tRPC React 钩子内部使用的 React QueryQueryClient对象:QueryClient 文档 -
queryClient:一个 React Query 的 QueryClient 实例- 注意:
queryClient和queryClientConfig只能二选一提供
- 注意:
-
transformer: 应用于输出数据的转换器。了解更多关于数据转换器的信息 -
abortOnUnmount: 决定组件卸载时是否取消进行中的请求。默认为false
overrides:(默认值:undefined)
ssr-布尔值(默认:false)
控制 tRPC 在服务端渲染页面时是否等待查询完成,默认值为 false。
responseMeta-回调函数
用于在服务端渲染时设置响应头与 HTTP 状态码。
示例
utils/trpc.tstsximport {createTRPCNext } from '@trpc/next';import type {AppRouter } from '../server/routers/_app';export consttrpc =createTRPCNext <AppRouter >({config (config ) {return {links : [/* [...] */],};},});
utils/trpc.tstsximport {createTRPCNext } from '@trpc/next';import type {AppRouter } from '../server/routers/_app';export consttrpc =createTRPCNext <AppRouter >({config (config ) {return {links : [/* [...] */],};},});