メインコンテンツへスキップ
バージョン: 11.x

Next.js Pages Routerでのセットアップ

非公式ベータ版翻訳

このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →

注意

このガイドはNext.js Pages Router向けです。React Server Componentsを利用したNext.js App Routerを使用している場合は、RSCドキュメントを参照してください。

推奨ファイル構造

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 install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zod

Next.js連携機能は、React Query連携とNext.js固有の統合機能を組み合わせたものです。

2. 厳格モードを有効化

Zodを使用した入力検証を行う場合は、tsconfig.jsonで厳格モード(strict mode)を有効化してください:

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.tsinitTRPC関数を使用してtRPCバックエンドを初期化し、最初のルーターを作成します。ここではシンプルな「hello world」ルーターとプロシージャを作成します。tRPC APIの詳細な作成方法については以下を参照してください:

View sample backend
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.io/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.io/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(config) {
return {
links: [
httpBatchLink({
/**
* If you want to use SSR, you need to use the server's full URL
* @see https://trpc.io/docs/v11/ssr
**/
url: `${getBaseUrl()}/api/trpc`,
// You can pass any HTTP headers you wish here
async headers() {
return {
// authorization: getAuthCookie(),
};
},
}),
],
};
},
/**
* @see https://trpc.io/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(config) {
return {
links: [
httpBatchLink({
/**
* If you want to use SSR, you need to use the server's full URL
* @see https://trpc.io/docs/v11/ssr
**/
url: `${getBaseUrl()}/api/trpc`,
// You can pass any HTTP headers you wish here
async headers() {
return {
// authorization: getAuthCookie(),
};
},
}),
],
};
},
/**
* @see https://trpc.io/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クライアントを設定するオブジェクトを返す関数です。この関数はNext.jsのreqオブジェクトなどにアクセスできるctx入力を受け取り、以下のプロパティを含むオブジェクトを返します:

  • 必須:

  • tRPCクライアントとサーバー間のデータフローをカスタマイズするlinks詳細

  • 任意:

  • tRPC Reactフック内部で使用されるReact QueryQueryClientの設定オブジェクトqueryClientConfigQueryClientドキュメント

  • queryClient: React QueryのQueryClientインスタンス

    • 注記: queryClientqueryClientConfigのどちらか一方のみを指定可能です。
  • transformer: 送信ペイロードに適用するトランスフォーマー。データトランスフォーマーに関する詳細

  • abortOnUnmount: コンポーネントのアンマウント時に処理中のリクエストをキャンセルするかどうか。デフォルトはfalseです。

overrides: (デフォルト: undefined)

React Queryフックのオーバーライド設定

ssr-boolean (デフォルト: 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(config) {
/* [...] */
},
});
utils/trpc.ts
tsx
import { createTRPCNext } from '@trpc/next';
import type { AppRouter } from '../pages/api/trpc/[trpc]';
export const trpc = createTRPCNext<AppRouter>({
config(config) {
/* [...] */
},
});

次のステップ

認可設定ミドルウェアエラーハンドリングなどについてドキュメントを参照してください。

@trpc/react-queryの使用にあたり、クエリミューテーションに関する情報も参照できます。