본문 바로가기
버전: 11.x

Next.js Pages Router로 설정하기

비공식 베타 번역

이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →

주의

이 가이드는 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 install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@latest zod
AI 에이전트

AI 코딩 에이전트를 사용하는 경우 더 나은 코드 생성을 위해 tRPC 스킬을 설치하세요:

bash
npx @tanstack/intent@latest install
bash
npx @tanstack/intent@latest install

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 생성에 대한 자세한 내용은 다음을 참조하세요:

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/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/server/adapters
export default trpcNext.createNextApiHandler({
router: appRouter,
createContext: () => ({}),
});
참고

위 백엔드는 추천 파일 구조를 사용하지만, 선호한다면 API 핸들러에 직접 모든 내용을 넣을 수도 있습니다.

4. tRPC 훅 생성

API의 타입 시그니처를 기반으로 강력한 타입의 훅 세트를 생성하려면 createTRPCNext 함수를 사용하세요.

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/client/nextjs/pages-router/ssr
**/
url: `${getBaseUrl()}/api/trpc`,
 
// You can pass any HTTP headers you wish here
async headers() {
return {
// authorization: getAuthCookie(),
};
},
}),
],
};
},
/**
* @see https://trpc.io/docs/client/nextjs/pages-router/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/client/nextjs/pages-router/ssr
**/
url: `${getBaseUrl()}/api/trpc`,
 
// You can pass any HTTP headers you wish here
async headers() {
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.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 속성(NextPageContext 타입)을 가진 객체를 인자로 받으며, 이를 통해 서버 사이드 렌더링 중 Next.js req 객체에 접근할 수 있습니다. 반환된 객체는 다음 속성을 포함할 수 있습니다:

  • 필수:

  • tRPC 클라이언트와 서버 간 데이터 흐름을 커스터마이즈하는 links 자세히 보기

  • 선택 사항:

  • tRPC React 훅 내부에서 사용되는 React Query QueryClient의 구성 객체 queryClientConfig: 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 '../server/routers/_app';
 
export const trpc = createTRPCNext<AppRouter>({
config(config) {
return {
links: [
/* [...] */
],
};
},
});
utils/trpc.ts
tsx
import { createTRPCNext } from '@trpc/next';
import type { AppRouter } from '../server/routers/_app';
 
export const trpc = createTRPCNext<AppRouter>({
config(config) {
return {
links: [
/* [...] */
],
};
},
});

다음 단계

인증, 미들웨어, 오류 처리 등에 대해 알아보려면 문서를 계속 탐색하세요.

@trpc/react-query를 사용 중이므로 쿼리뮤테이션에 대한 정보도 확인할 수 있습니다.