Usage
Recommended file structure
Recommended but not enforced file structure. This is what you get when starting from the examples.
.
├── 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 as a plugin
└── [..]
1. Create a tRPC router
Initialize your tRPC backend using the initTRPC
function and create your first router.
server/trpc/trpc.ts
import { initTRPC } from '@trpc/server'// Avoid exporting the entire t-object since it's not very// descriptive and can be confusing to newcomers used to t// meaning translation in i18n libraries.const t = initTRPC.create()// Base router and procedure helpersexport const router = t.routerexport const publicProcedure = t.procedure
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 to a single root appRouter
.2. Create tRPC client plugin
Create a set of strongly-typed composables using your API's type signature.
plugins/client.ts
import { httpBatchLink } from '@trpc/client'import { createTRPCNuxtProxyClient } from 'trpc-nuxt/client'import type { AppRouter } from '@/server/trpc/routers'export default defineNuxtPlugin(() => { const client = createTRPCNuxtProxyClient<AppRouter>({ links: [ httpBatchLink({ /** * If you want to use SSR, you need to use the server's full URL * @link https://trpc.io/docs/ssr **/ url: 'http://localhost:3000/api/trpc', }), ], }) return { provide: { client, }, }})
3. Make API requests
pages/index.vue
<script setup lang="ts">const { $client } = useNuxtApp()// query and mutate uses useAsyncData under the hoodconst { data, pending, error } = await $client.hello.query({ text: 'client' })</script><template> <div v-if="pending"> Loading... </div> <div v-else-if="error?.data?.code"> Error: {{ error.data.code }} </div> <div v-else> <p>{{ hello.data?.greeting }}</p> </div></template>