Next.js Pages Router로 설정하기
이 가이드는 Next.js Pages Router를 위한 것입니다. Next.js App Router를 사용 중이시라면 App Router 설정 가이드를 참고해 주세요.
권장 파일 구조
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
- deno
npm install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zod
yarn add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zod
pnpm add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zod
bun add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zod
deno add npm:@trpc/server npm:@trpc/client npm:@trpc/react-query npm:@trpc/next npm:@tanstack/react-query@latest npm:zod
AI 코딩 에이전트를 사용하는 경우, 더 나은 코드 생성을 위해 tRPC 스킬을 설치하세요:
bashnpx @tanstack/intent@latest install
bashnpx @tanstack/intent@latest install
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 라우터 생성
src/server/trpc.ts에서 initTRPC 함수를 사용하여 tRPC 백엔드를 초기화하고 첫 번째 라우터를 생성하세요. 여기서는 간단한 "hello world" 라우터와 프로시저를 만들지만, tRPC API 생성에 대한 더 자세한 정보는 다음을 참고하세요:
- tRPC 정보에 대한 빠른 시작 가이드 및 백엔드 사용 문서
- Next.js 서버 내에서 tRPC를 마운트하는 방법에 대한 Next.js 어댑터 문서
샘플 백엔드 보기
server/trpc.tstsimport {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.constt =initTRPC .create ();// Base router and procedure helpersexport constrouter =t .router ;export constprocedure =t .procedure ;
server/trpc.tstsimport {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.constt =initTRPC .create ();// Base router and procedure helpersexport constrouter =t .router ;export constprocedure =t .procedure ;
server/routers/_app.tstsimport {z } from 'zod';import {procedure ,router } from '../trpc';export constappRouter =router ({hello :procedure .input (z .object ({text :z .string (),}),).query ((opts ) => {return {greeting : `hello ${opts .input .text }`,};}),});// export type definition of APIexport typeAppRouter = typeofappRouter ;
server/routers/_app.tstsimport {z } from 'zod';import {procedure ,router } from '../trpc';export constappRouter =router ({hello :procedure .input (z .object ({text :z .string (),}),).query ((opts ) => {return {greeting : `hello ${opts .input .text }`,};}),});// export type definition of APIexport typeAppRouter = typeofappRouter ;
pages/api/trpc/[trpc].tstsimport * astrpcNext from '@trpc/server/adapters/next';import {appRouter } from '../../../server/routers/_app';// export API handler// @link https://trpc.io/docs/server/adaptersexport defaulttrpcNext .createNextApiHandler ({router :appRouter ,createContext : () => ({}),});
pages/api/trpc/[trpc].tstsimport * astrpcNext from '@trpc/server/adapters/next';import {appRouter } from '../../../server/routers/_app';// export API handler// @link https://trpc.io/docs/server/adaptersexport defaulttrpcNext .createNextApiHandler ({router :appRouter ,createContext : () => ({}),});
위 백엔드는 권장 파일 구조를 사용하지만, 원하는 경우 API 핸들러에 직접 모든 것을 포함시켜 간단하게 유지할 수도 있습니다.
4. tRPC 훅 생성
createTRPCNext 함수를 사용하여 API의 타입 시그니처에서 강력하게 타입 지정된 훅 세트를 생성하세요.
utils/trpc.tstsximport {httpBatchLink } from '@trpc/client';import {createTRPCNext } from '@trpc/next';import type {AppRouter } from '../server/routers/_app';functiongetBaseUrl () {if (typeofwindow !== '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 consttrpc =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/client/nextjs/pages-router/ssr**/url : `${getBaseUrl ()}/api/trpc`,// You can pass any HTTP headers you wish hereasyncheaders () {return {// authorization: getAuthCookie(),};},}),],};},/*** @see https://trpc.io/docs/client/nextjs/pages-router/ssr**/ssr : false,});
utils/trpc.tstsximport {httpBatchLink } from '@trpc/client';import {createTRPCNext } from '@trpc/next';import type {AppRouter } from '../server/routers/_app';functiongetBaseUrl () {if (typeofwindow !== '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 consttrpc =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/client/nextjs/pages-router/ssr**/url : `${getBaseUrl ()}/api/trpc`,// You can pass any HTTP headers you wish hereasyncheaders () {return {// authorization: getAuthCookie(),};},}),],};},/*** @see https://trpc.io/docs/client/nextjs/pages-router/ssr**/ssr : false,});
createTRPCNext는 tRPC-v9 상호 운용성 모드와 함께 작동하지 않습니다. 상호 운용성을 사용하여 v9에서 마이그레이션 중인 경우 기존 tRPC 초기화 방식을 계속 사용해야 합니다.
5. _app.tsx 설정
다음과 유사하게 루트 앱 페이지를 trpc.withTRPC HOC로 감싸세요:
pages/_app.tsxtsximport type {AppType } from 'next/app';import {trpc } from '../utils/trpc';constMyApp :AppType = ({Component ,pageProps }) => {return <Component {...pageProps } />;};export defaulttrpc .withTRPC (MyApp );
pages/_app.tsxtsximport type {AppType } from 'next/app';import {trpc } from '../utils/trpc';constMyApp :AppType = ({Component ,pageProps }) => {return <Component {...pageProps } />;};export defaulttrpc .withTRPC (MyApp );
6. API 요청 보내기
모든 설정이 완료되었습니다!
이제 방금 생성한 React 훅을 사용하여 API를 호출할 수 있습니다. 자세한 내용은 React Query 통합을 참고하세요.
pages/index.tsxtsximport {trpc } from '../utils/trpc';export default functionIndexPage () {consthello =trpc .hello .useQuery ({text : 'client' });if (!hello .data ) {return <div >Loading...</div >;}return (<div ><p >{hello .data .greeting }</p ></div >);}
pages/index.tsxtsximport {trpc } from '../utils/trpc';export default functionIndexPage () {consthello =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 속성(NextPageContext 타입)이 포함된 객체를 수신합니다. 반환 값에는 다음 속성이 포함될 수 있습니다:
- 필수:
- tRPC 클라이언트와 tRPC 서버 간의 데이터 흐름을 사용자 정의하기 위한
links. 자세히 보기. - 선택:
queryClientConfig: tRPC React 훅이 내부적으로 사용하는 React QueryQueryClient에 대한 구성 객체: QueryClient 문서queryClient: React Query QueryClient 인스턴스- 참고:
queryClient또는queryClientConfig중 하나만 제공할 수 있습니다.
- 참고:
transformer: 나가는 페이로드에 적용되는 트랜스포머입니다. Data Transformers에서 자세히 알아보세요.abortOnUnmount: 컴포넌트가 언마운트될 때 진행 중인 요청을 취소할지 결정합니다. 기본값은false입니다.
overrides: (기본값: undefined)
React Query 훅에 대한 오버라이드를 구성합니다.
ssr-boolean (기본값: false)
tRPC가 페이지를 서버 사이드 렌더링할 때 쿼리를 대기해야 하는지 여부를 결정합니다. 기본값은 false입니다.
responseMeta-콜백
서버 사이드 렌더링 시 요청 헤더와 HTTP 상태를 설정할 수 있습니다.
예시
utils/trpc.tstsximport {createTRPCNext } from '@trpc/next';import type {AppRouter } from '../server/routers/_app';export consttrpc =createTRPCNext <AppRouter >({config (config ) {return {links : [/* [...] */],};},});
utils/trpc.tstsximport {createTRPCNext } from '@trpc/next';import type {AppRouter } from '../server/routers/_app';export consttrpc =createTRPCNext <AppRouter >({config (config ) {return {links : [/* [...] */],};},});