mirror of
https://github.com/ArthurDanjou/trpc-nuxt.git
synced 2026-01-14 12:14:40 +01:00
166 lines
4.1 KiB
Markdown
166 lines
4.1 KiB
Markdown
---
|
|
title: Usage
|
|
description: tRPC-Nuxt provides first class integration with tRPC.
|
|
---
|
|
|
|
# Usage
|
|
|
|
## Recommended file structure
|
|
|
|
Recommended but not enforced file structure. This is what you get when starting from [the examples](../main/example-apps.md).
|
|
|
|
```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 as a 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]
|
|
import { initTRPC } from '@trpc/server'
|
|
import { Context } from '@/server/trpc/context'
|
|
|
|
// 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.context<Context>().create()
|
|
|
|
// Base router and procedure helpers
|
|
export const router = t.router
|
|
export const publicProcedure = t.procedure
|
|
```
|
|
|
|
```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<typeof createContext>;
|
|
```
|
|
|
|
::
|
|
|
|
::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 { httpBatchLink, createTRPCProxyClient } from '@trpc/client'
|
|
import type { AppRouter } from '@/server/trpc/routers'
|
|
import { FetchError } from 'ofetch'
|
|
|
|
export default defineNuxtPlugin(() => {
|
|
const client = createTRPCProxyClient<AppRouter>({
|
|
links: [
|
|
httpBatchLink({
|
|
url: '/api/trpc',
|
|
|
|
|
|
/**
|
|
* Replace regular `fetch` with a `$fetch` from nuxt
|
|
*
|
|
* During server-side rendering, calling $fetch to fetch your internal API routes
|
|
* will directly call the relevant function (emulating the request),
|
|
* saving an additional API call.
|
|
*
|
|
* @see https://nuxt.com/docs/api/utils/dollarfetch
|
|
*/
|
|
fetch: (input, options) =>
|
|
globalThis.$fetch.raw(input.toString(), options)
|
|
.catch((e) => {
|
|
if (e instanceof FetchError && e.response)
|
|
return e.response
|
|
|
|
throw e
|
|
})
|
|
.then(response => ({
|
|
...response,
|
|
json: () => Promise.resolve(response._data),
|
|
})),
|
|
|
|
}),
|
|
],
|
|
})
|
|
|
|
return {
|
|
provide: {
|
|
client,
|
|
},
|
|
}
|
|
})
|
|
```
|
|
|
|
## 3. Make API requests
|
|
|
|
```vue [pages/index.vue]
|
|
<script setup lang="ts">
|
|
const { $client } = useNuxtApp()
|
|
|
|
const data = await $client.hello.query({ text: 'client' })
|
|
</script>
|
|
|
|
<template>
|
|
<p>{{data?.greeting }}</p>
|
|
</template>
|
|
```
|