--- title: Recommended description: tRPC-Nuxt provides first class integration with tRPC. --- # Recommended Usage Recommended but not enforced file structure. ```graphql . ├── server │ ├── api │ │ └── trpc │ │ └── [trpc].ts # <-- tRPC HTTP handler │ │ └── [..] │ ├── trpc │ │ ├── routers │ │ │ ├── index.ts # <-- main app router │ │ │ ├── todo.ts # <-- sub routers │ │ │ └── [..] │ │ ├── context.ts # <-- create app context │ │ └── trpc.ts # <-- procedure helpers ├── plugins │ ├── client.ts # <-- tRPC client plugin └── [..] ``` ## 1. Create a tRPC router Initialize your tRPC backend using the `initTRPC` function and create your first router. ::code-group ```ts [server/trpc/trpc.ts] /** * This is your entry point to setup the root configuration for tRPC on the server. * - `initTRPC` should only be used once per app. * - We export only the functionality that we use so we can enforce which base procedures should be used * * Learn how to create protected base procedures and other things below: * @see https://trpc.io/docs/v10/router * @see https://trpc.io/docs/v10/procedures */ import { initTRPC } from '@trpc/server' import { Context } from '~/server/trpc/context' const t = initTRPC.context().create() /** * Unprotected procedure **/ export const publicProcedure = t.procedure; export const router = t.router; export const middleware = t.middleware; ``` ```ts [server/trpc/routers/index.ts] import { z } from 'zod' import { publicProcedure, router } from '../trpc' export const appRouter = router({ hello: publicProcedure .input( z.object({ text: z.string().nullish(), }), ) .query(({ input }) => { return { greeting: `hello ${input?.text ?? 'world'}`, } }), }) // export type definition of API export type AppRouter = typeof appRouter ``` ```ts [server/api/trpc/[trpc].ts] import { createNuxtApiHandler } from 'trpc-nuxt' import { appRouter } from '~/server/trpc/routers' import { createContext } from '~/server/trpc/context' // export API handler export default createNuxtApiHandler({ router: appRouter, createContext, }) ``` ```ts [server/trpc/context.ts] import { inferAsyncReturnType } from '@trpc/server' /** * Creates context for an incoming request * @link https://trpc.io/docs/context */ export const createContext = () => ({}) export type Context = inferAsyncReturnType; ``` :: ::alert{type=info} If you need to split your router into several subrouters, you can implement them in the `server/trpc/routers` directory and import and [merge them](https://trpc.io/docs/v10/merging-routers) to a single root `appRouter`. :: ## 2. Create tRPC client plugin Create a strongly-typed plugin using your API's type signature. ```ts [plugins/client.ts] import { createTRPCNuxtClient, httpBatchLink } from 'trpc-nuxt/client' import type { AppRouter } from '~/server/trpc/routers' export default defineNuxtPlugin(() => { /** * createTRPCNuxtClient adds a `useQuery` composable * built on top of `useAsyncData`. */ const client = createTRPCNuxtClient({ links: [ httpBatchLink({ url: '/api/trpc', }), ], }) return { provide: { client, }, } }) ``` ## 3. Make an API request ```vue [pages/index.vue] ```