使用 Next.js 设置
推荐的文件结构
¥Recommended file structure
我们推荐这样的文件结构,尽管它不是由 tRPC 强制执行的。这就是你将在 我们的例子 中看到的内容。本页的其余部分将引导你完成将 tRPC 添加到此结构的过程。
¥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.
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└── [..]
将 tRPC 添加到现有的 Next.js 项目
¥Add tRPC to existing Next.js project
1. 安装依赖
¥ Install deps
- npm
- yarn
- pnpm
- bun
sh
npm install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
sh
npm install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
sh
yarn add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
sh
yarn add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
sh
pnpm add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
sh
pnpm add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
sh
bun add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
sh
bun add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
Next.js 集成实际上是我们的 React 查询集成 和一些 Next.js 特定集成的组合。
¥The Next.js integration is actually a combination of our React Query Integration and some Next.js specific integrations.
2. 启用严格模式
¥ Enable strict mode
如果你想使用 Zod 进行输入验证,请确保你已在 tsconfig.json
中启用严格模式:
¥If you want to use Zod for input validation, make sure you have enabled strict mode in your tsconfig.json
:
tsconfig.jsondiff
"compilerOptions": {+ "strict": true}
tsconfig.jsondiff
"compilerOptions": {+ "strict": true}
如果严格模式太苛刻,你至少要启用 strictNullChecks
:
¥If strict mode is too harsh, you'll at least want to enable strictNullChecks
:
tsconfig.jsondiff
"compilerOptions": {+ "strictNullChecks": true}
tsconfig.jsondiff
"compilerOptions": {+ "strictNullChecks": true}
3. 创建 tRPC 路由
¥ Create a tRPC router
使用 initTRPC
函数在 src/server/trpc.ts
中初始化你的 tRPC 后端,并创建你的第一个路由。我们将在这里制作一个简单的 "你好世界" 路由和程序 - 但有关创建 tRPC API 的更深入信息,你应该参考:
¥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
Next.js 适配器文档 用于在 Next.js 服务器中安装 tRPC。
¥the Next.js Adapter docs for mounting tRPC within your Next.js server.
View sample backend
server/trpc.tsts
import { 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 t = initTRPC.create();// Base router and procedure helpersexport const router = t.router;export const procedure = t.procedure;
server/trpc.tsts
import { 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 t = initTRPC.create();// Base router and procedure helpersexport const router = t.router;export const procedure = t.procedure;
server/routers/_app.tsts
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 definition of APIexport type AppRouter = typeof appRouter;
server/routers/_app.tsts
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 definition of APIexport type AppRouter = typeof appRouter;
pages/api/trpc/[trpc].tsts
import * as trpcNext from '@trpc/server/adapters/next';import { appRouter } from '../../../server/routers/_app';// export API handler// @see https://trpc.nodejs.cn/docs/server/adaptersexport default trpcNext.createNextApiHandler({router: appRouter,createContext: () => ({}),});
pages/api/trpc/[trpc].tsts
import * as trpcNext from '@trpc/server/adapters/next';import { appRouter } from '../../../server/routers/_app';// export API handler// @see https://trpc.nodejs.cn/docs/server/adaptersexport default trpcNext.createNextApiHandler({router: appRouter,createContext: () => ({}),});
上面的后端使用的是 推荐的文件结构,但如果你愿意,你可以保持简单并将所有内容放入 直接 API 处理程序。
¥The backend above is using the recommended file structure, but you can keep it simple and put everything in an API handler directly if you prefer.
4. 创建 tRPC 钩子
¥ Create tRPC hooks
使用 createTRPCNext
函数根据 API 的类型签名创建一组强类型钩子。
¥use the createTRPCNext
function to create a set of strongly-typed hooks from your API's type signature.
utils/trpc.tstsx
import { httpBatchLink } from '@trpc/client';import { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../server/routers/_app';function getBaseUrl() {if (typeof window !== '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 const trpc = createTRPCNext<AppRouter>({config(opts) {return {links: [httpBatchLink({/*** If you want to use SSR, you need to use the server's full URL* @link https://trpc.nodejs.cn/docs/ssr**/url: `${getBaseUrl()}/api/trpc`,// You can pass any HTTP headers you wish hereasync headers() {return {// authorization: getAuthCookie(),};},}),],};},/*** @link https://trpc.nodejs.cn/docs/ssr**/ssr: false,});
utils/trpc.tstsx
import { httpBatchLink } from '@trpc/client';import { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../server/routers/_app';function getBaseUrl() {if (typeof window !== '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 const trpc = createTRPCNext<AppRouter>({config(opts) {return {links: [httpBatchLink({/*** If you want to use SSR, you need to use the server's full URL* @link https://trpc.nodejs.cn/docs/ssr**/url: `${getBaseUrl()}/api/trpc`,// You can pass any HTTP headers you wish hereasync headers() {return {// authorization: getAuthCookie(),};},}),],};},/*** @link https://trpc.nodejs.cn/docs/ssr**/ssr: false,});
createTRPCNext
不适用于 tRPC-v9 互操作模式。如果你使用互操作从 v9 迁移,则应继续使用 初始化 tRPC 的旧方法。
¥createTRPCNext
does not work with the tRPC-v9 interop mode. If you are migrating from v9 using interop, you should continue using the old way of initializing tRPC.
5. 配置 _app.tsx
¥ Configure _app.tsx
将你的根应用页面封装在 trpc.withTRPC
HOC 中,类似于:
¥Wrap your root app page in the trpc.withTRPC
HOC, similar to this:
pages/_app.tsxtsx
import type { AppType } from 'next/app';import { trpc } from '../utils/trpc';const MyApp: AppType = ({ Component, pageProps }) => {return <Component {...pageProps} />;};export default trpc.withTRPC(MyApp);
pages/_app.tsxtsx
import type { AppType } from 'next/app';import { trpc } from '../utils/trpc';const MyApp: AppType = ({ Component, pageProps }) => {return <Component {...pageProps} />;};export default trpc.withTRPC(MyApp);
6. 发送 API 请求
¥ Make an API request
你都准备好了!
¥You're all set!
你现在可以使用刚刚创建的 React hook 来调用 API。欲了解更多详情,请参阅 React 查询集成
¥You can now use the React hooks you have just created to invoke your API. For more detail see the React Query Integration
pages/index.tsxtsx
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>);}
pages/index.tsxtsx
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>);}
createTRPCNext()
选项
¥createTRPCNext()
options
config
-回调
¥config
-callback
config
参数是一个返回配置 tRPC 和 React Query 客户端的对象的函数。此函数有一个 ctx
输入,可让你访问 Next.js req
对象等。返回值可以包含以下属性:
¥The config
-argument is a function that returns an object that configures the tRPC and React Query clients. This function has a ctx
input that gives you access to the Next.js req
object, among other things. The returned value can contain the following properties:
必需的:
¥Required:
links
自定义 tRPC 客户端和 tRPC 服务器之间的数据流。阅读更多。¥
links
to customize the flow of data between tRPC Client and the tRPC Server. Read more.可选的:
¥Optional:
queryClientConfig
:tRPC React hooks 在内部使用的 React QueryQueryClient
的配置对象:查询客户端文档¥
queryClientConfig
: a configuration object for the React QueryQueryClient
used internally by the tRPC React hooks: QueryClient docsqueryClient
:React 查询 查询客户端实例¥
queryClient
: a React Query QueryClient instance注意:你只能提供
queryClient
或queryClientConfig
。¥Note: You can only provide either a
queryClient
or aqueryClientConfig
.
transformer
:应用于传出有效负载的转换器。了解有关 数据转换器 的更多信息¥
transformer
: a transformer applied to outgoing payloads. Read more about Data TransformersabortOnUnmount
:确定是否在组件卸载时取消正在进行的请求。默认为false
。¥
abortOnUnmount
: determines if in-flight requests will be cancelled on component unmount. This defaults tofalse
.
overrides
:(默认:undefined
)
¥overrides
: (default: undefined
)
¥Configure overrides for React Query's hooks.
ssr
-布尔值(默认值:false
)
¥ssr
-boolean (default: false
)
服务器端渲染页面时 tRPC 是否应等待查询。默认为 false
。
¥Whether tRPC should await queries when server-side rendering a page. Defaults to false
.
responseMeta
-回调
¥responseMeta
-callback
能够在服务器端渲染时设置请求标头和 HTTP 状态。
¥Ability to set request headers and HTTP status when server-side rendering.
示例
¥Example
utils/trpc.tstsx
import { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../pages/api/trpc/[trpc]';export const trpc = createTRPCNext<AppRouter>({config(opts) {/* [...] */},ssr: true,responseMeta(opts) {const { clientErrors } = opts;if (clientErrors.length) {// propagate first http error from API callsreturn {status: clientErrors[0].data?.httpStatus ?? 500,};}// cache full page for 1 day + revalidate once every secondconst ONE_DAY_IN_SECONDS = 60 * 60 * 24;return {'Cache-Control': `s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS}`,};},});
utils/trpc.tstsx
import { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../pages/api/trpc/[trpc]';export const trpc = createTRPCNext<AppRouter>({config(opts) {/* [...] */},ssr: true,responseMeta(opts) {const { clientErrors } = opts;if (clientErrors.length) {// propagate first http error from API callsreturn {status: clientErrors[0].data?.httpStatus ?? 500,};}// cache full page for 1 day + revalidate once every secondconst ONE_DAY_IN_SECONDS = 60 * 60 * 24;return {'Cache-Control': `s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS}`,};},});
下一步
¥Next steps
浏览其余文档以了解有关 authorization、middlewares 和 错误处理 等内容的更多信息。
¥Browse the rest of the docs to learn more about things like authorization, middlewares, and error handling.
既然你正在使用 @trpc/react-query
,你还可以找到有关 queries 和 mutations 的信息。
¥You can also find information about queries and mutations now that you're using @trpc/react-query
.