跳到主要內容
版本: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 路由器

src/server/trpc.ts 中使用 initTRPC 函式初始化你的 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.dev.org.tw/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.dev.org.tw/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 `https://#:${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.dev.org.tw/docs/v11/ssr
**/
url: `${getBaseUrl()}/api/trpc`,
// You can pass any HTTP headers you wish here
async headers() {
return {
// authorization: getAuthCookie(),
};
},
}),
],
};
},
/**
* @link https://trpc.dev.org.tw/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 `https://#:${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.dev.org.tw/docs/v11/ssr
**/
url: `${getBaseUrl()}/api/trpc`,
// You can pass any HTTP headers you wish here
async headers() {
return {
// authorization: getAuthCookie(),
};
},
}),
],
};
},
/**
* @link https://trpc.dev.org.tw/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 hooks 來呼叫您的 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:React Query QueryClient 的設定物件,由 tRPC React hooks 內部使用:QueryClient 文件
  • queryClient:React Query QueryClient 執行個體
    • 注意:您只能提供 queryClientqueryClientConfig
  • transformer:套用至傳出有效負載的轉換器。進一步了解 資料轉換器
  • abortOnUnmount:決定在元件解除安裝時是否取消進行中的要求。預設為 false

overrides:(預設:undefined

設定 React Query 的 hooks 的覆寫

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,您也可以找到關於 查詢突變 的資訊。