Configuración con Next.js
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Estructura de archivos recomendada
Recomendamos una estructura de archivos como esta, aunque no es obligatoria en tRPC. Esto es lo que verás en nuestros ejemplos. El resto de esta página te guiará para agregar tRPC en esta estructura.
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└── [..]
Agregar tRPC a un proyecto existente de Next.js
1. Instalar dependencias
- npm
- yarn
- pnpm
- bun
shnpm install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
shnpm install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
shyarn add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
shyarn add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
shpnpm add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
shpnpm add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
shbun add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
shbun add @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query@4 zod
La integración con Next.js combina nuestra integración con React Query con algunas integraciones específicas de Next.js.
2. Habilitar modo estricto
Si quieres usar Zod para validación de entradas, asegúrate de habilitar el modo estricto en tu tsconfig.json:
tsconfig.jsondiff"compilerOptions": {+ "strict": true}
tsconfig.jsondiff"compilerOptions": {+ "strict": true}
Si el modo estricto es demasiado restrictivo, al menos deberías habilitar strictNullChecks:
tsconfig.jsondiff"compilerOptions": {+ "strictNullChecks": true}
tsconfig.jsondiff"compilerOptions": {+ "strictNullChecks": true}
3. Crear un enrutador tRPC
Inicializa tu backend tRPC en src/server/trpc.ts usando la función initTRPC, y crea tu primer enrutador. Aquí haremos un enrutador y procedimiento simple de "hola mundo". Para información más profunda sobre cómo crear tu API tRPC, consulta:
-
la guía de inicio rápido y la documentación de uso del backend para información sobre tRPC
-
la documentación del adaptador para Next.js para montar tRPC en tu servidor Next.js.
View sample backend
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.const t = initTRPC.create();// Base router and procedure helpersexport const router = t.router;export const procedure = 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.const t = initTRPC.create();// Base router and procedure helpersexport const router = t.router;export const procedure = t.procedure;
server/routers/_app.tstsimport { 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.tstsimport { 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].tstsimport * as trpcNext from '@trpc/server/adapters/next';import { appRouter } from '../../../server/routers/_app';// export API handler// @link https://trpc.io/docs/server/adaptersexport default trpcNext.createNextApiHandler({router: appRouter,createContext: () => ({}),});
pages/api/trpc/[trpc].tstsimport * as trpcNext from '@trpc/server/adapters/next';import { appRouter } from '../../../server/routers/_app';// export API handler// @link https://trpc.io/docs/server/adaptersexport default trpcNext.createNextApiHandler({router: appRouter,createContext: () => ({}),});
El backend anterior usa la estructura de archivos recomendada, pero puedes simplificar y poner todo directamente en un manejador de API si prefieres.
4. Crear hooks tRPC
Usa la función createTRPCNext para crear un conjunto de hooks fuertemente tipados según la firma de tipos de tu API.
utils/trpc.tstsximport { 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(config) {return {links: [httpBatchLink({/*** If you want to use SSR, you need to use the server's full URL* @see https://trpc.io/docs/ssr**/url: `${getBaseUrl()}/api/trpc`,// You can pass any HTTP headers you wish hereasync headers() {return {// authorization: getAuthCookie(),};},}),],};},/*** @see https://trpc.io/docs/ssr**/ssr: false,});
utils/trpc.tstsximport { 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(config) {return {links: [httpBatchLink({/*** If you want to use SSR, you need to use the server's full URL* @see https://trpc.io/docs/ssr**/url: `${getBaseUrl()}/api/trpc`,// You can pass any HTTP headers you wish hereasync headers() {return {// authorization: getAuthCookie(),};},}),],};},/*** @see https://trpc.io/docs/ssr**/ssr: false,});
createTRPCNext no funciona con el modo de interoperabilidad de tRPC-v9. Si estás migrando desde v9 usando interoperabilidad, debes continuar usando la forma anterior de inicializar tRPC.
5. Configurar _app.tsx
Envuelve tu página raíz de la aplicación en el HOC trpc.withTRPC, de forma similar a esto:
pages/_app.tsxtsximport 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.tsxtsximport type { AppType } from 'next/app';import { trpc } from '../utils/trpc';const MyApp: AppType = ({ Component, pageProps }) => {return <Component {...pageProps} />;};export default trpc.withTRPC(MyApp);
6. Realizar una solicitud a la API
¡Estás listo!
Ahora puedes usar los hooks de React que acabas de crear para invocar tu API. Para más detalles, consulta la Integración con React Query
pages/index.tsxtsximport { 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.tsxtsximport { 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>);}
Opciones de createTRPCNext()
Callback config
El argumento config es una función que devuelve un objeto que configura los clientes de tRPC y React Query. Esta función tiene una entrada ctx que te da acceso al objeto req de Next.js, entre otras cosas. El valor devuelto puede contener las siguientes propiedades:
-
Obligatorias:
-
linkspara personalizar el flujo de datos entre el cliente tRPC y el servidor tRPC. Lee más. -
Opcionales:
-
queryClientConfig: objeto de configuración para elQueryClientde React Query usado internamente por los hooks de React de tRPC: Documentación de QueryClient -
queryClient: una instancia de QueryClient de React Query- Nota: Solo puedes proporcionar un
queryCliento unqueryClientConfig, no ambos.
- Nota: Solo puedes proporcionar un
-
transformer: transformador aplicado a las cargas útiles salientes. Más información sobre Transformadores de Datos -
abortOnUnmount: determina si las solicitudes en curso se cancelarán al desmontar el componente. Por defecto esfalse.
overrides: (predeterminado: undefined)
Configura sobreescrituras para los hooks de React Query.
ssr-booleano (predeterminado: false)
Indica si tRPC debe esperar las consultas al renderizar una página en el servidor. Por defecto es false.
responseMeta-callback
Permite establecer encabezados de solicitud y estado HTTP durante el renderizado en el servidor.
Ejemplo
utils/trpc.tstsximport { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../pages/api/trpc/[trpc]';export const trpc = createTRPCNext<AppRouter>({config(config) {/* [...] */},ssr: true,responseMeta(opts) {const { clientErrors } = opts;if (clientErrors.length) {// propagate first http error from API callsreturn {status: clientErrors[0].data?.httpStatus ?? 500,};}// cache full page for 1 day + revalidate once every secondconst ONE_DAY_IN_SECONDS = 60 * 60 * 24;return {'Cache-Control': `s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS}`,};},});
utils/trpc.tstsximport { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../pages/api/trpc/[trpc]';export const trpc = createTRPCNext<AppRouter>({config(config) {/* [...] */},ssr: true,responseMeta(opts) {const { clientErrors } = opts;if (clientErrors.length) {// propagate first http error from API callsreturn {status: clientErrors[0].data?.httpStatus ?? 500,};}// cache full page for 1 day + revalidate once every secondconst ONE_DAY_IN_SECONDS = 60 * 60 * 24;return {'Cache-Control': `s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS}`,};},});
Próximos pasos
Explora el resto de la documentación para aprender sobre temas como autorización, middlewares y manejo de errores.
También puedes encontrar información sobre consultas y mutaciones ahora que estás usando @trpc/react-query.