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└── [..]
既存の Next.js プロジェクトに tRPC を追加する
1. 依存関係のインストール
- npm
- yarn
- pnpm
- bun
npm install @trpc/server@next @trpc/client@next @trpc/react-query@next @trpc/next@next @tanstack/react-query@latest zod
yarn add @trpc/server@next @trpc/client@next @trpc/react-query@next @trpc/next@next @tanstack/react-query@latest zod
pnpm add @trpc/server@next @trpc/client@next @trpc/react-query@next @trpc/next@next @tanstack/react-query@latest zod
bun add @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. strict モードを有効にする
Zod を入力検証に使用する場合、tsconfig.json
で strict モードが有効になっていることを確認してください
tsconfig.jsondiff
"compilerOptions": {+ "strict": true}
tsconfig.jsondiff
"compilerOptions": {+ "strict": true}
strict モードが厳しすぎる場合は、少なくとも strictNullChecks
を有効にする必要があります
tsconfig.jsondiff
"compilerOptions": {+ "strictNullChecks": true}
tsconfig.jsondiff
"compilerOptions": {+ "strictNullChecks": true}
3. tRPC ルーターを作成する
initTRPC
関数を使用して src/server/trpc.ts
に tRPC バックエンドを初期化し、最初のルーターを作成します。ここでは、簡単な「hello world」ルーターとプロシージャを作成します。tRPC API の作成の詳細については、以下を参照してください。
- tRPC については、クイックスタートガイドとバックエンドの使い方を参照してください。
- Next.js サーバー内に tRPC をマウントする方法については、Next.js アダプターのドキュメントを参照してください。
サンプルバックエンドを見る
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// @link https://trpc.dokyumento.jp/docs/v11/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// @link https://trpc.dokyumento.jp/docs/v11/server/adaptersexport default trpcNext.createNextApiHandler({router: appRouter,createContext: () => ({}),});
上記のバックエンドは推奨ファイル構造を使用していますが、必要に応じてAPI ハンドラーに直接すべてを配置することもできます。
4. tRPC フックを作成する
createTRPCNext
関数を使用して、API の型シグネチャから厳密に型指定されたフックのセットを作成します。
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.dokyumento.jp/docs/v11/ssr**/url: `${getBaseUrl()}/api/trpc`,// You can pass any HTTP headers you wish hereasync headers() {return {// authorization: getAuthCookie(),};},}),],};},/*** @link https://trpc.dokyumento.jp/docs/v11/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.dokyumento.jp/docs/v11/ssr**/url: `${getBaseUrl()}/api/trpc`,// You can pass any HTTP headers you wish hereasync headers() {return {// authorization: getAuthCookie(),};},}),],};},/*** @link https://trpc.dokyumento.jp/docs/v11/ssr**/ssr: false,});
createTRPCNext
は tRPC-v9 の相互運用モードでは動作しません。相互運用を使用して v9 から移行する場合は、以前の tRPC の初期化方法を引き続き使用してください。
5. _app.tsx
を設定する
ルートアプリページを trpc.withTRPC
HOC でラップします。例:
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);
(コード例は省略)
これで準備完了です!
作成した React フックを使用して API を呼び出すことができるようになりました。詳細については、React Query 統合を参照してください。
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()
オプション
config
コールバック
config
引数は、tRPC および React Query クライアントを設定するオブジェクトを返す関数です。この関数には、Next.js の req
オブジェクトなどにアクセスできる ctx
入力があります。戻り値には、次のプロパティを含めることができます。
- 必須:
links
: tRPC クライアントと tRPC サーバー間のデータフローをカスタマイズします。詳細はこちら。- オプション
queryClientConfig
: tRPC React フックで内部的に使用される React Query のQueryClient
の設定オブジェクトです。QueryClient ドキュメントqueryClient
: React Query のQueryClient インスタンス- **注:**
queryClient
またはqueryClientConfig
のいずれか一方のみを提供できます。
- **注:**
transformer
: 送信ペイロードに適用されるトランスフォーマーです。データトランスフォーマーの詳細をご覧ください。abortOnUnmount
: コンポーネントのアンマウント時に処理中のリクエストをキャンセルするかどうかを決定します。デフォルトはfalse
です。
overrides
: (デフォルト: undefined
)
React Query のフックのオーバーライドを設定します。
ssr
ブール値 (デフォルト: false
)
ページのサーバーサイドレンダリング時に tRPC がクエリを待機するかどうか。デフォルトは false
です。
responseMeta
コールバック
サーバーサイドレンダリング時にリクエストヘッダーと HTTP ステータスを設定できます。
例
utils/trpc.tstsx
import { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../pages/api/trpc/[trpc]';export const trpc = createTRPCNext<AppRouter>({config(opts) {/* [...] */},});
utils/trpc.tstsx
import { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../pages/api/trpc/[trpc]';export const trpc = createTRPCNext<AppRouter>({config(opts) {/* [...] */},});