tRpc - Move Fast and Break Nothing. End-to-end typesafe APIs made easy. Experience the full power of TypeScript inference to boost productivity for your NUXT full-stack application.
This blog is a companion to the video walkthrough of getting a Nuxt 3 application up and running with tRpc using the trpc-nuxt module.
This is the first video in the series, additional content will be created for you to follow along and build a Full-Stack Typescript Application with Nuxt and tRPC.
tPRC Nuxt Module - wobsoriano/trpc-nuxt Documentation
Installation
Create a Nuxt 3 App using the cli
npx nuxi@latest init trpc-nuxt-app
Install the tRPC Libraries and Zod for schema and parameter validation.
npm install @trpc/server @trpc/client trpc-nuxt zod
Configuration
modify nuxt.config.ts
to transpile that into an ES5 bundle.
export default defineNuxtConfig({
build: {
transpile: ['trpc-nuxt']
}
})
Add Boilerplate Code
Entrypoint into trpc server; the embedded documentation explains what is going on.
// 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 '../trpc/context';
const t = initTRPC.context<Context>().create();
/**
* Unprotected procedure
**/
export const publicProcedure = t.procedure;
export const router = t.router;
export const middleware = t.middleware;
The context
, this is where you can put things that you want all routes to have access to. We will be putting out database client here so we can access it through the context in our routes
// 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>;
The routes, can be broken up into separate files so we will place an index file in the /trpc/routers
directory to support that in the future, but for now, we will just add the routes/endpoints directly to the router
// 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;
The hello
route has an optional string parameter text
which is used in the query
to return the greeting with the text
parameter value or the static string hello
.
Next, create the tRPC Plugin so you can access the trpc client throughout your application.
You will be able to access the client using const { $trpcClient } = useNuxtApp();
anywhere in your nuxt app client.
// plugins/trpc-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 trpcClient = createTRPCNuxtClient<AppRouter>({
links: [
httpBatchLink({
url: '/api/trpc',
}),
],
});
return {
provide: {
trpcClient,
},
};
});
Next, we create and initialize the API Handler using theappRouter
we create and we pass in the function to create the context
// server/api/trpc/[trpc].ts
import { createNuxtApiHandler } from 'trpc-nuxt';
import { appRouter } from '../../trpc/routers';
import { createContext } from '../../trpc/context';
// export API handler
export default createNuxtApiHandler({
router: appRouter,
createContext,
});
Test Code In Application
Now that everything is in place we can test the API call in the app.vue
Code to call API from client
// app.vue
<script setup lang="ts">
const { $trpcClient } = useNuxtApp();
console.log($trpcClient);
const { data } = await $trpcClient.hello.useQuery({text : "smith"});
</script>
<template>
<p>app</p>
<div>
<p>{{ data?.greeting }}</p>
</div>
</template>
Source Code
Links
trpc-nuxt documentation - trpc-nuxt.vercel.app
trpc documentation - trpc.io
Social Media
Twitter - https://twitter.com/aaronksaunders
Instagram - https://www.instagram.com/aaronksaunders/
Clearly Innovative Inc - https://www.clearlyinnovative.com