Aller au contenu principal
Version : 9.x

Utilisation avec Next.js

Traduction Bêta Non Officielle

Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →

astuce

Si vous utilisez tRPC dans un nouveau projet, envisagez d'utiliser l'un des projets d'exemple comme point de départ ou référence : Projets d'exemple tRPC

tRPC et Next.js sont un mariage parfait ! Next.js vous permet de construire facilement votre client et serveur dans une seule base de code. Cela facilite le partage des types entre eux.

tRPC inclut des outils dédiés pour offrir une expérience développeur aussi fluide que possible avec Next.js.

Structure de fichiers recommandée

Structure de fichiers recommandée mais non imposée. C'est ce que vous obtenez en partant des exemples.

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
└── [..]

Ajouter tRPC à un projet Next.js existant

1. Installer les dépendances

bash
yarn add @trpc/client @trpc/server @trpc/react @trpc/next zod react-query@3
bash
yarn add @trpc/client @trpc/server @trpc/react @trpc/next zod react-query@3
  • React Query : @trpc/react fournit une fine surcouche au-dessus de @tanstack/react-query. C'est une dépendance peer obligatoire.

  • Zod : la plupart des exemples utilisent Zod pour la validation des entrées et nous le recommandons vivement, bien que ce ne soit pas obligatoire. Vous pouvez utiliser une bibliothèque de validation de votre choix (Yup, Superstruct, io-ts, etc). En fait, tout objet contenant une méthode parse, create ou validateSync fonctionnera.

2. Activer le mode strict

Si vous souhaitez utiliser Zod pour la validation des entrées, assurez-vous d'avoir activé le mode strict dans votre tsconfig.json :

json
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strict": true
}
}
json
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strict": true
}
}

Si le mode strict est trop contraignant, activez au moins strictNullChecks :

json
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strictNullChecks": true
}
}
json
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strictNullChecks": true
}
}

3. Créer un routeur tRPC

Implémentez votre routeur tRPC dans ./pages/api/trpc/[trpc].ts. Si vous devez diviser votre routeur en plusieurs sous-routeurs, implémentez-les dans un répertoire server à la racine de votre projet, puis importez-les dans ./pages/api/trpc/[trpc].ts et fusionnez-les dans un appRouter racine unique.

View sample router
./pages/api/trpc/[trpc].ts
ts
import * 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 API
export type AppRouter = typeof appRouter;
// export API handler
export default trpcNext.createNextApiHandler({
router: appRouter,
createContext: () => null,
});
./pages/api/trpc/[trpc].ts
ts
import * 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 API
export type AppRouter = typeof appRouter;
// export API handler
export default trpcNext.createNextApiHandler({
router: appRouter,
createContext: () => null,
});

4. Créer les hooks tRPC

Créez un ensemble de hooks fortement typés en utilisant la signature de type de votre API.

utils/trpc.ts
tsx
import { createReactQueryHooks } from '@trpc/react';
import type { AppRouter } from '../pages/api/trpc/[trpc]';
export const trpc = createReactQueryHooks<AppRouter>();
// => { useQuery: ..., useMutation: ...}
utils/trpc.ts
tsx
import { createReactQueryHooks } from '@trpc/react';
import type { AppRouter } from '../pages/api/trpc/[trpc]';
export const trpc = createReactQueryHooks<AppRouter>();
// => { useQuery: ..., useMutation: ...}

5. Configurer _app.tsx

La fonction createReactQueryHooks attend certains paramètres transmis via l'API Context. Pour définir ces paramètres, créez un _app.tsx personnalisé en utilisant le composant d'ordre supérieur withTRPC :

pages/_app.tsx
tsx
import { 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.tsx
tsx
import { 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. Effectuer des requêtes API

pages/index.tsx
tsx
import { 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.tsx
tsx
import { 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>
);
}

Options de withTRPC()

Callback config

L'argument config est une fonction renvoyant un objet configurant les clients tRPC et React Query. Cette fonction reçoit un contexte ctx donnant accès à l'objet req de Next.js entre autres. L'objet retourné peut contenir les propriétés suivantes :

  • Une seule de ces options est obligatoire :

    • url : l'URL de votre API
    • links : pour personnaliser le flux de données entre le client tRPC et le serveur tRPC. En savoir plus
  • Optionnel :

    • queryClientConfig : objet de configuration pour le QueryClient de React Query utilisé en interne par les hooks React tRPC : Documentation QueryClient
    • headers : objet ou fonction renvoyant un objet pour les requêtes tRPC sortantes
    • transformer : transformateur appliqué aux payloads sortants. En savoir plus sur les Transformateurs de données
    • fetch : personnalise l'implémentation de fetch utilisée en interne par tRPC
    • AbortController : personnalise l'implémentation d'AbortController utilisée en interne par tRPC

ssr-booléen (par défaut : false)

Détermine si tRPC doit attendre les requêtes lors du rendu côté serveur d'une page. Valeur par défaut false.

responseMeta-callback

Permet de définir les en-têtes de requête et le statut HTTP lors du rendu côté serveur.

Exemple

pages/_app.tsx
tsx
export default withTRPC<AppRouter>({
config(config) {
/* [...] */
},
ssr: true,
responseMeta({ clientErrors, ctx }) {
if (clientErrors.length) {
// propagate first http error from API calls
return {
status: clientErrors[0].data?.httpStatus ?? 500,
};
}
// cache full page for 1 day + revalidate once every second
const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
return {
'Cache-Control': `s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS}`,
};
},
})(MyApp);
pages/_app.tsx
tsx
export default withTRPC<AppRouter>({
config(config) {
/* [...] */
},
ssr: true,
responseMeta({ clientErrors, ctx }) {
if (clientErrors.length) {
// propagate first http error from API calls
return {
status: clientErrors[0].data?.httpStatus ?? 500,
};
}
// cache full page for 1 day + revalidate once every second
const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
return {
'Cache-Control': `s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS}`,
};
},
})(MyApp);

Prochaines étapes

Consultez la documentation de @trpc/react pour plus d'informations sur l'exécution de Requêtes et Mutations dans vos composants.