Uso con Next.js
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Si estás usando tRPC en un nuevo proyecto, considera utilizar uno de los proyectos de ejemplo como punto de partida o referencia: Proyectos de ejemplo de tRPC
¡tRPC y Next.js son una combinación perfecta! Next.js te permite construir tu cliente y servidor juntos en un mismo código base. Esto facilita compartir tipos entre ellos.
tRPC incluye herramientas dedicadas para que la experiencia de desarrollo con Next.js sea lo más fluida posible.
Estructura de archivos recomendada
Estructura de archivos recomendada pero no obligatoria. Esto es lo que obtendrás al comenzar con los ejemplos.
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│ │ └── createRouter.ts # <-- router helper│ └── 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│ │ └── createRouter.ts # <-- router helper│ └── utils│ └── trpc.ts # <-- your typesafe tRPC hooks└── [..]
Agregar tRPC a un proyecto existente de Next.js
1. Instalar dependencias
bashyarn add @trpc/client @trpc/server @trpc/react @trpc/next zod react-query@3
bashyarn add @trpc/client @trpc/server @trpc/react @trpc/next zod react-query@3
-
React Query:
@trpc/reactproporciona un envoltorio ligero sobre @tanstack/react-query. Es necesario como dependencia peer. -
Zod: la mayoría de los ejemplos usan Zod para validación de entradas y lo recomendamos encarecidamente, aunque no es obligatorio. Puedes usar una biblioteca de validación de tu elección (Yup, Superstruct, io-ts, etc). De hecho, cualquier objeto que contenga un método
parse,createovalidateSyncfuncionará.
2. Habilitar modo estricto
Si quieres usar Zod para validación de entradas, asegúrate de habilitar el modo estricto en tu tsconfig.json:
json// tsconfig.json{// ..."compilerOptions": {// ..."strict": true}}
json// tsconfig.json{// ..."compilerOptions": {// ..."strict": true}}
Si el modo estricto es demasiado, al menos habilita strictNullChecks:
json// tsconfig.json{// ..."compilerOptions": {// ..."strictNullChecks": true}}
json// tsconfig.json{// ..."compilerOptions": {// ..."strictNullChecks": true}}
3. Crear un enrutador tRPC
Implementa tu enrutador tRPC en ./pages/api/trpc/[trpc].ts. Si necesitas dividir tu enrutador en varios subenrutadores, impleméntalos en un directorio server de nivel superior en la raíz de tu proyecto, luego impórtalos en ./pages/api/trpc/[trpc].ts y fusiónalos en un único appRouter raíz.
View sample router
./pages/api/trpc/[trpc].tstsimport * as trpc from '@trpc/server';import * as trpcNext from '@trpc/server/adapters/next';import { z } from 'zod';export const appRouter = trpc.router().query('hello', {input: z.object({text: z.string().nullish(),}).nullish(),resolve({ input }) {return {greeting: `hello ${input?.text ?? 'world'}`,};},});// export type definition of APIexport type AppRouter = typeof appRouter;// export API handlerexport default trpcNext.createNextApiHandler({router: appRouter,createContext: () => null,});
./pages/api/trpc/[trpc].tstsimport * as trpc from '@trpc/server';import * as trpcNext from '@trpc/server/adapters/next';import { z } from 'zod';export const appRouter = trpc.router().query('hello', {input: z.object({text: z.string().nullish(),}).nullish(),resolve({ input }) {return {greeting: `hello ${input?.text ?? 'world'}`,};},});// export type definition of APIexport type AppRouter = typeof appRouter;// export API handlerexport default trpcNext.createNextApiHandler({router: appRouter,createContext: () => null,});
4. Crear hooks tRPC
Crea un conjunto de hooks fuertemente tipados usando la firma de tipos de tu API.
utils/trpc.tstsximport { createReactQueryHooks } from '@trpc/react';import type { AppRouter } from '../pages/api/trpc/[trpc]';export const trpc = createReactQueryHooks<AppRouter>();// => { useQuery: ..., useMutation: ...}
utils/trpc.tstsximport { createReactQueryHooks } from '@trpc/react';import type { AppRouter } from '../pages/api/trpc/[trpc]';export const trpc = createReactQueryHooks<AppRouter>();// => { useQuery: ..., useMutation: ...}
5. Configurar _app.tsx
La función createReactQueryHooks espera ciertos parámetros pasados mediante la Context API. Para establecer estos parámetros, crea un _app.tsx personalizado usando el componente de orden superior withTRPC:
pages/_app.tsxtsximport { withTRPC } from '@trpc/next';import { AppType } from 'next/dist/shared/lib/utils';import type { AppRouter } from './api/trpc/[trpc]';const MyApp: AppType = ({ Component, pageProps }) => {return <Component {...pageProps} />;};export default withTRPC<AppRouter>({config(config) {/*** If you want to use SSR, you need to use the server's full URL* @see https://trpc.io/docs/ssr*/const url = process.env.VERCEL_URL? `https://${process.env.VERCEL_URL}/api/trpc`: 'http://localhost:3000/api/trpc';return {url,/*** @see https://tanstack.com/query/v3/docs/react/reference/QueryClient*/// queryClientConfig: { defaultOptions: { queries: { staleTime: 60 } } },};},/*** @see https://trpc.io/docs/ssr*/ssr: true,})(MyApp);
pages/_app.tsxtsximport { withTRPC } from '@trpc/next';import { AppType } from 'next/dist/shared/lib/utils';import type { AppRouter } from './api/trpc/[trpc]';const MyApp: AppType = ({ Component, pageProps }) => {return <Component {...pageProps} />;};export default withTRPC<AppRouter>({config(config) {/*** If you want to use SSR, you need to use the server's full URL* @see https://trpc.io/docs/ssr*/const url = process.env.VERCEL_URL? `https://${process.env.VERCEL_URL}/api/trpc`: 'http://localhost:3000/api/trpc';return {url,/*** @see https://tanstack.com/query/v3/docs/react/reference/QueryClient*/// queryClientConfig: { defaultOptions: { queries: { staleTime: 60 } } },};},/*** @see https://trpc.io/docs/ssr*/ssr: true,})(MyApp);
6. Realizar solicitudes a la API
pages/index.tsxtsximport { trpc } from '../utils/trpc';export default function IndexPage() {const hello = trpc.useQuery(['hello', { 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.useQuery(['hello', { text: 'client' }]);if (!hello.data) {return <div>Loading...</div>;}return (<div><p>{hello.data.greeting}</p></div>);}
Opciones de withTRPC()
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:
-
Exactamente uno de estos es obligatorio:
url: tu URL de la API.links: para personalizar el flujo de datos entre el cliente tRPC y el servidor tRPC. Leer más.
-
Opcionales:
queryClientConfig: objeto de configuración para elQueryClientde React Query usado internamente por los hooks React de tRPC: Documentación de QueryClientheaders: objeto o función que devuelve un objeto de solicitudes salientes tRPCtransformer: transformador aplicado a las cargas útiles salientes. Más información sobre Transformadores de datosfetch: personaliza la implementación defetchusada internamente por tRPCAbortController: personaliza la implementación deAbortControllerusada internamente por tRPC
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
pages/_app.tsxtsxexport default withTRPC<AppRouter>({config(config) {/* [...] */},ssr: true,responseMeta({ clientErrors, ctx }) {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}`,};},})(MyApp);
pages/_app.tsxtsxexport default withTRPC<AppRouter>({config(config) {/* [...] */},ssr: true,responseMeta({ clientErrors, ctx }) {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}`,};},})(MyApp);
Próximos pasos
Consulta la documentación de @trpc/react para información adicional sobre cómo ejecutar Consultas y Mutaciones dentro de tus componentes.