跳至主要内容
版本:11.x

使用 Next.js 设置

我们推荐使用这样的文件结构,尽管 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
└── [..]

将 tRPC 添加到现有的 Next.js 项目

1. 安装依赖项

npm install @trpc/server@next @trpc/client@next @trpc/react-query@next @trpc/next@next @tanstack/react-query@latest zod

Next.js 集成实际上是我们 React Query 集成 和一些 Next.js 特定集成的组合。

2. 启用严格模式

如果您想使用 Zod 进行输入验证,请确保您已在 tsconfig.json 中启用了严格模式

tsconfig.json
diff
"compilerOptions": {
+ "strict": true
}
tsconfig.json
diff
"compilerOptions": {
+ "strict": true
}

如果严格模式过于严格,您至少需要启用 strictNullChecks

tsconfig.json
diff
"compilerOptions": {
+ "strictNullChecks": true
}
tsconfig.json
diff
"compilerOptions": {
+ "strictNullChecks": true
}

3. 创建 tRPC 路由器

使用 initTRPC 函数在 src/server/trpc.ts 中初始化您的 tRPC 后端,并创建您的第一个路由器。我们将在这里创建一个简单的“hello world”路由器和过程 - 但有关创建 tRPC API 的更深入信息,您应该参考

查看示例后端
server/trpc.ts
ts
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 helpers
export const router = t.router;
export const procedure = t.procedure;
server/trpc.ts
ts
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 helpers
export const router = t.router;
export const procedure = t.procedure;

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 definition of API
export type AppRouter = typeof appRouter;
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 definition of API
export type AppRouter = typeof appRouter;

pages/api/trpc/[trpc].ts
ts
import * as trpcNext from '@trpc/server/adapters/next';
import { appRouter } from '../../../server/routers/_app';
// export API handler
// @link https://trpc.node.org.cn/docs/v11/server/adapters
export default trpcNext.createNextApiHandler({
router: appRouter,
createContext: () => ({}),
});
pages/api/trpc/[trpc].ts
ts
import * as trpcNext from '@trpc/server/adapters/next';
import { appRouter } from '../../../server/routers/_app';
// export API handler
// @link https://trpc.node.org.cn/docs/v11/server/adapters
export default trpcNext.createNextApiHandler({
router: appRouter,
createContext: () => ({}),
});
注意

上面的后端使用的是 推荐的文件结构,但如果您愿意,可以保持简单,并将所有内容放在 API 处理程序中

4. 创建 tRPC 钩子

使用 createTRPCNext 函数从 API 的类型签名创建一组强类型钩子。

utils/trpc.ts
tsx
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 path
return '';
if (process.env.VERCEL_URL)
// reference for vercel.com
return `https://${process.env.VERCEL_URL}`;
if (process.env.RENDER_INTERNAL_HOSTNAME)
// reference for render.com
return `http://${process.env.RENDER_INTERNAL_HOSTNAME}:${process.env.PORT}`;
// assume localhost
return `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.node.org.cn/docs/v11/ssr
**/
url: `${getBaseUrl()}/api/trpc`,
// You can pass any HTTP headers you wish here
async headers() {
return {
// authorization: getAuthCookie(),
};
},
}),
],
};
},
/**
* @link https://trpc.node.org.cn/docs/v11/ssr
**/
ssr: false,
});
utils/trpc.ts
tsx
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 path
return '';
if (process.env.VERCEL_URL)
// reference for vercel.com
return `https://${process.env.VERCEL_URL}`;
if (process.env.RENDER_INTERNAL_HOSTNAME)
// reference for render.com
return `http://${process.env.RENDER_INTERNAL_HOSTNAME}:${process.env.PORT}`;
// assume localhost
return `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.node.org.cn/docs/v11/ssr
**/
url: `${getBaseUrl()}/api/trpc`,
// You can pass any HTTP headers you wish here
async headers() {
return {
// authorization: getAuthCookie(),
};
},
}),
],
};
},
/**
* @link https://trpc.node.org.cn/docs/v11/ssr
**/
ssr: false,
});
注意

createTRPCNext 不适用于 tRPC-v9 互操作模式。如果您使用互操作从 v9 迁移,您应该继续使用 初始化 tRPC 的旧方法

5. 配置 _app.tsx

将您的根应用程序页面包装在 trpc.withTRPC HOC 中,类似于此

pages/_app.tsx
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);
pages/_app.tsx
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);

6. 发出 API 请求

您已全部设置!

您现在可以使用刚刚创建的 React 钩子来调用您的 API。有关更多详细信息,请参阅 React Query 集成

pages/index.tsx
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>
);
}
pages/index.tsx
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>
);
}

createTRPCNext() 选项

config-回调

config 参数是一个函数,它返回一个对象,该对象配置 tRPC 和 React Query 客户端。此函数有一个 ctx 输入,它使您可以访问 Next.js req 对象,以及其他内容。返回值可以包含以下属性

  • 必需:
  • links 用于自定义 tRPC 客户端和 tRPC 服务器之间的数据流。 了解更多
  • 可选
  • queryClientConfig:用于 tRPC React 钩子内部使用的 React Query QueryClient 的配置对象: QueryClient 文档
  • queryClient:一个 React Query QueryClient 实例
    • 注意:您只能提供 queryClientqueryClientConfig
  • transformer:应用于传出有效负载的转换器。阅读有关 数据转换器 的更多信息
  • abortOnUnmount:确定在组件卸载时是否会取消正在进行的请求。默认值为 false

overrides: (默认值:undefined)

配置 React Query 钩子的覆盖

ssr-布尔值 (默认值:false)

tRPC 在服务器端渲染页面时是否应该等待查询。默认值为 false

responseMeta-回调

能够在服务器端渲染时设置请求标头和 HTTP 状态。

示例

utils/trpc.ts
tsx
import { createTRPCNext } from '@trpc/next';
import type { AppRouter } from '../pages/api/trpc/[trpc]';
export const trpc = createTRPCNext<AppRouter>({
config(opts) {
/* [...] */
},
});
utils/trpc.ts
tsx
import { createTRPCNext } from '@trpc/next';
import type { AppRouter } from '../pages/api/trpc/[trpc]';
export const trpc = createTRPCNext<AppRouter>({
config(opts) {
/* [...] */
},
});

下一步

浏览其余文档以了解有关 授权中间件错误处理 等内容的更多信息。

您还可以找到有关 查询变异 的信息,因为您现在正在使用 @trpc/react-query@next@next。