As web applications demand more streamlined, type-safe, and efficient data-fetching mechanisms, integrating tRPC with Next.js 14 becomes essential. This article will walk you through the step-by-step process of setting up tRPC with Next.js 14 App Router, ensuring you leverage the full potential of both tools.
Overview of tRPC and Next.js 14
Introduction to tRPCtRPC stands for TypeScript Remote Procedure Call. It is an end-to-end typesafe API framework that allows you to build APIs using TypeScript interfaces and types. The primary advantage of tRPC is its ability to infer types directly from your backend logic, ensuring consistency and type safety across your application.
Features and Benefits of tRPCType Safety: Ensure that your API calls are consistent and error-free.
No Schema Duplication: Utilize TypeScript for both client and server without needing separate schema definitions.
Fast and Efficient: Minimize the overhead by directly calling server functions from the client.
Framework Agnostic: While we're focusing on Next.js in this article, tRPC supports various frameworks.
Next.js has long been a go-to framework for building React applications with server-side rendering (SSR) capabilities. The Next.js 14 release enhances these features with its App Router, providing an even more optimized and developer-friendly routing solution.
Initial Setup
Before diving into the integration, let's get a Next.js 14 project up and running and install the necessary dependencies for tRPC.
Creating a Next.js 14 Projectnpx create-next-app@latest my-app --typescript
cd my-app
Installing Dependenciesnpm install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query zod
Configuring TypeScript
Configuration of TypeScript is paramount for leveraging the type safety provided by tRPC. Ensure that strict mode is enabled in your project.
Enabling Strict Mode in TypeScriptOpen your tsconfig.json
and add the following settings:
{
"compilerOptions": {
"strict": true,
"strictNullChecks": true
}
}
Setting Up tRPC
With the project set up and dependencies installed, let's configure the tRPC backend and server.
Creating the tRPC BackendCreate a file src/server/trpc.ts
and initialize tRPC with a basic router:
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
const t = initTRPC.create();
export const appRouter = t.router({
hello: t.procedure
.input(z.object({ text: z.string() }))
.query(({ input }) => {
return { greeting: `hello ${input.text}` };
}),
});
export type AppRouter = typeof appRouter;
Configuring the tRPC Router in the BackendCreate a file src/pages/api/trpc/[trpc].ts
and configure the tRPC HTTP handler:
import { createNextApiHandler } from '@trpc/next';
import { appRouter } from '../../../server/trpc';
export default createNextApiHandler({
router: appRouter,
createContext: () => null,
});
Integrating tRPC with Next.js 14 App Router
The integration of tRPC with Next.js 14's App Router allows us to create a seamless, type-safe data-fetching experience.
Creating tRPC HooksCreate a file src/utils/trpc.ts
and configure the tRPC client:
import { httpBatchLink } from '@trpc/client';
import { createTRPCNext } from '@trpc/next';
import type { AppRouter } from '../server/trpc';
export const trpc = createTRPCNext<AppRouter>({
config() {
return {
links: [
httpBatchLink({
url: '/api/trpc',
}),
],
};
},
ssr: false,
});
Configuring _app.tsx
for tRPC IntegrationWrap your root app page with the tRPC higher-order component (HOC):
import type { AppType } from 'next/app';
import { trpc } from '../utils/trpc';
const MyApp: AppType = ({ Component, pageProps }) => (
<Component {...pageProps} />
);
export default trpc.withTRPC(MyApp);
Making API Requests Using tRPC HooksUtilize the React hooks to make API requests in your components. For example, in pages/index.tsx
:
import { trpc } from '../utils/trpc';
export default function IndexPage() {
const hello = trpc.hello.useQuery({ text: 'client' });
if (!hello.data) {
return <div>Loading...</div>;
}
return (
<div>
<p>{hello.data.greeting}</p>
</div>
);
}
Setting up Prisma for Database Integration
While optional, integrating Prisma ORM can significantly enhance your project's data management capabilities.
Installing and Configuring Prisma ORMyarn add prisma @prisma/client
npx prisma init
Configure your database in the .env
file and set up Prisma schema in prisma/schema.prisma
.
Creating tRPC Endpoints and Procedures
Let's create tRPC endpoints to perform CRUD operations using the integrated Prisma ORM.
Defining Routers and Procedures in tRPCCreate a postRouter
with CRUD operations:
import { router, publicProcedure } from './trpc';
import { z } from 'zod';
import { prisma } from '../lib/prisma';
export const postRouter = router({
createPost: publicProcedure
.input(z.object({
title: z.string(),
content: z.string(),
}))
.mutation(async ({ input }) => {
const post = await prisma.post.create({
data: input,
});
return post;
}),
getPosts: publicProcedure.query(async () => {
const posts = await prisma.post.findMany();
return posts;
}),
});
Conclusion
In this article, we have meticulously walked through the setup and integration of tRPC with Next.js 14, ensuring a robust and type-safe development experience. Whether you're building small-scale applications or large enterprise solutions, this setup provides a solid foundation. If you're looking for further enhancements and a streamlined content management experience, consider exploring Wisp CMS, which offers comprehensive solutions tailored for modern web development needs.
By leveraging the combined powers of tRPC and Next.js 14, you're well on your way to creating highly efficient, maintainable, and type-safe web applications.
Start building your next project with tRPC and Next.js 14 today, and explore the world of seamless web development!