avatarDaniel Craciun

Summary

The webpage provides a comprehensive guide on integrating tRPC with Next.js 13 to create type-safe, interactive, and fast web applications.

Abstract

The article "Next.js 13 + tRPC: A Match Made in Heaven" delves into the synergistic combination of Next.js 13 and tRPC for web development. It outlines the steps to set up a Next.js 13 project environment, install necessary dependencies, and create a tRPC server. The guide explains how to configure tRPC for both client-side and server-side components, demonstrating practical examples of tRPC procedures in action. The author emphasizes the benefits of tRPC's type-safe API development and its seamless integration with Next.js 13, which enhances developer productivity and application performance. The article concludes by highlighting the advantages of having a fully functional, scalable, and type-safe backend within a Next.js 13 project.

Opinions

  • The author believes that the integration of Next.js 13 and tRPC is highly advantageous for web developers, describing it as a "powerful synergy" and a "match made in heaven."
  • The use of tRPC is praised for providing a type-safe way to build APIs, which maximizes endpoint security and improves the developer experience.
  • The guide is written with the intention of not wasting the reader's time, indicating a value for efficiency and practicality.
  • The author suggests that the workflow of a Next.js 13 project can be significantly improved by using tRPC, implying that it can increase productivity by a factor of ten.
  • The article encourages reader engagement by inviting questions and feedback, showing a commitment to community support and continuous learning.
  • The conclusion expresses enthusiasm about the potential of tRPC within Next.js 13 projects, suggesting that it can greatly enhance the development process and the quality of the final product.

Next.js 13 + tRPC: A Match Made in Heaven

Fictional image of Heaven

Dive into the powerful synergy between Next.js 13 and tRPC in this comprehensive guide.

Discover how this dynamic duo empowers web developers to create blazing-fast and highly interactive applications. From leveraging Next.js 13’s cutting-edge features to harnessing tRPC's facilities that provide a type-safe way to build APIs.

Without wasting any more of your time, lets get straight into it!

Table of Contents

  • Setup Next.js 13 Project Environment
  • Dependencies Installation
  • Creating a tRPC Server
  • Configuring tRPC for Client-Side and Server-Side
  • Server tRPC Example
  • Client tRPC Example

Setup Next.js 13 Project Environment

To setup a Next.js project, please check out the instructions here. The installation process generally consists of running the following command in the terminal.

npx create-next-app@latest

Dependencies Installation

Open a terminal within your project directory, and execute one of the following commands to get started:

npm install @trpc/client @trpc/server @trpc/react-query @tanstack/react-query zod
yarn add @trpc/client @trpc/server @trpc/react-query @tanstack/react-query zod
pnpm add @trpc/client @trpc/server @trpc/react-query @tanstack/react-query zod

Creating a tRPC Server

  1. Go into the src/ folder in your Next.js 13 project — or inside the root of your project if you didn’t select the src/ folder option — and create a new folder called server with a file called trpc.ts:
import { initTRPC } from "@trpc/server";

const t = initTRPC.create();

export const router = t.router;
export const publicProcedure = t.procedure;

This is simple boilerplate code to allow you to create API procedures and routers in your Next.js 13 backend.

2. Inside the src/server/ directory, create a new file called index.ts:

import { z } from "zod"

import { publicProcedure, router } from "./trpc"

export const appRouter = router({
  getData: publicProcedure.query(async () => {
    // Here you would fetch data from a database in a
    // real-life application.
    console.log("getData")
    return "getData"
  }),
  setData: publicProcedure
    .input(z.string())
    .mutation(async ({ input }) => {
      // Here you would update a database using the
      // input string passed into the procedure
      console.log(input)
      return input
    }),
})
// This type will be used as a reference later...
export type AppRouter = typeof appRouter
  • We import the publicProcedure and router functions defined inside the trpc.ts file.
  • Next we create an appRouter, which acts as a hub for your API procedures.
  • Inside the appRouter I defined a trivial getData and setData function for tutorial’s sake.
  • In the setData function, the code input(z.string()) ensures the input data is validated using zod maximizing endpoint security and developer experience.

3. Go inside the app/ directory, and create a sequence of files and directories as follows: api/trpc/[trpc]/route.ts.

import { appRouter } from "@/server"
import { fetchRequestHandler } from "@trpc/server/adapters/fetch"

const handler = (req: Request) =>
  fetchRequestHandler({
    endpoint: "/api/trpc",
    req,
    router: appRouter,
    createContext: () => ({}),
  })

export { handler as GET, handler as POST }

This creates an API endpoint that is called when a procedure is run.

Configuring tRPC for Client-Side and Server-Side

  1. Inside the app/ directory, create a folder called _trpc and with a file called client.ts. This defines a tRPC instance that is usable inside all your Next.js 13 client-components.
import { type AppRouter } from "@/server"
import { createTRPCReact } from "@trpc/react-query"

export const trpc = createTRPCReact<AppRouter>({})

2. Within the same folder, create a file called serverClient.ts to define a tRPC instance that works for all server-side components.

import { appRouter } from "@/server"
import { httpBatchLink } from "@trpc/client"

export const serverClient = appRouter.createCaller({
  links: [
    httpBatchLink({
      url: "http://localhost:3000/api/trpc",
    }),
  ],
})

NOTE: You will need to change the url http:localhost:3000 when deploying your code to production, In this case, you should conditionally select the url as follows:

import { appRouter } from "@/server"
import { httpBatchLink } from "@trpc/client"

const url =
  process.env.NODE_ENV === "production"
    ? "your-production-url/api/trpc"
    : "http://localhost:3000/api/trpc"

export const serverClient = appRouter.createCaller({
  links: [
    httpBatchLink({ url }),
  ],
})

Server tRPC Example

Lets run our procedures that we’ve defined earlier inside a server component! Open up app/page.tsx and copy the following code:

import { serverClient } from "./_trpc/serverClient"

export default async function page() {
  const data = await serverClient.getData()
  const dataSet = await serverClient.setData("test-data")

  return (
    <main>
        <div>{data}</div>
        <div>{dataSet}</div>
    </main>
  )
}

Run the application using npm run dev inside a terminal window, then visit localhost:3000/; you should see the data within the UI and within the server-side terminal window.

Client tRPC Example

Now lets run the same procedures inside a client component! Open up app/page.tsx and copy the following code:

"use client"

import { trpc } from "@/app/_trpc/client"

export default async function page() {
  const getData = trpc.getData.useQuery({
      // your react-query properties ...
  })

  const setData = trpc.setData.useMutation({
      // your react-query properties ...
  })

  return (
    <main>
        <div>{getData.data}</div>
        <div>{setData.data}</div>
    </main>
  )
}

Conclusion:

In both the server-side and client-side examples, you may have noticed that the data returned is 100% type-safe! This is the main reason tRPC is so great!

Your Next.js 13 project workflow should now increase tenfold as the data from external endpoints is 100% validated + type-safe, ready to bring your projects to life.

I hope you’ve enjoyed this article! You now have a fully functional and scalable tRPC backend within your Next.js 13 project!

If you have any questions and concerns, please be sure to let me know, and as always, stay tuned for more! 👍

Level Up Coding

Thanks for being a part of our community! Before you go:

🔔 Follow us: Twitter | LinkedIn | Newsletter

🚀👉 Join the Level Up talent collective and find an amazing job

Nextjs
React
API
Typescript
Web Development
Recommended from ReadMedium
avatarFrancisco Moretti
Next.js Authentication Best Practices

3 min read