Skip to content

03: trpc setup - #3

Merged
AMMAR-62 merged 1 commit into
mainfrom
03--trpc-setup
Dec 22, 2025
Merged

03: trpc setup#3
AMMAR-62 merged 1 commit into
mainfrom
03--trpc-setup

Conversation

@AMMAR-62

@AMMAR-62 AMMAR-62 commented Dec 22, 2025

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

New Features

  • Integrated server-client data fetching with intelligent query caching (30-second stale time), reducing unnecessary requests and improving app responsiveness.
  • Added tRPC-based API integration for streamlined and efficient client-server communication with automatic request batching support.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 22, 2025

Copy link
Copy Markdown

Walkthrough

This PR introduces a tRPC-based data fetching architecture with server-side routing and client-side React Query integration. New dependencies enable @tanstack/react-query and tRPC packages. Core tRPC setup includes initialization, query client configuration, and a router exposing a getUsers procedure. Server and client integration layers provide per-request query clients and provider patterns, replacing the previous direct Prisma-based data fetching on the page component with prefetch/hydration workflow.

Changes

Cohort / File(s) Change Summary
Dependencies & Configuration
package.json
Added @tanstack/react-query, @trpc/client, @trpc/server, @trpc/tanstack-react-query, client-only, and server-only dependencies to enable tRPC and React Query functionality.
TRPC Core Setup
src/trpc/init.ts, src/trpc/query-client.ts, src/trpc/routers/_app.ts
Introduced tRPC initialization with context creation, query client factory with 30-second stale time, and router with getUsers procedure calling prisma.user.findMany().
Server-Side Integration
src/trpc/server.tsx, src/app/api/trpc/[trpc]/route.ts
Added server-only tRPC setup with per-request query client, options proxy, and caller; exposed fetchRequestHandler as GET/POST routes for /api/trpc endpoint.
Client-Side Provider
src/trpc/client.tsx
Created client-side tRPC React provider with httpBatchLink transport, query client provisioning, and singleton browser instance management via getQueryClient.
Application Integration
src/app/layout.tsx, src/app/page.tsx, src/app/client.tsx
Wrapped RootLayout with TRPCReactProvider; refactored page to server-prefetch queries and dehydrate state into HydrationBoundary; added Client component for Suspense-bounded data rendering.

Sequence Diagram

sequenceDiagram
    participant Server as Server<br/>(Next.js)
    participant QueryCache as Query<br/>Cache
    participant Hydration as Hydration<br/>Boundary
    participant Client as Client<br/>Component
    participant TRPCLink as TRPC<br/>Client

    Server->>QueryCache: getQueryClient() + trpc.getUsers.prefetch()
    QueryCache-->>Server: Cached results
    Server->>Hydration: dehydrate(queryClient)
    Server->>Client: Render with dehydrated state
    Client->>Hydration: Wrap Client in HydrationBoundary
    Hydration->>Client: Provide dehydrated state + Suspense
    Client->>TRPCLink: useTRPC + useSuspenseQuery
    TRPCLink->>Client: Hydrate from cache (or fetch if stale)
    Client-->>Server: Render users
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Heterogeneous logic patterns: Five new tRPC files introduce distinct responsibilities (init, query client, router, server/client coordination) each requiring separate reasoning
  • Integration complexity: Coordination between server-side prefetch, dehydration, hydration boundaries, and client-side query subscription requires understanding multi-layer data flow
  • Provider pattern implementation: Client-side provider with singleton caching and React cache integration warrants careful review for correctness
  • Existing component modifications: Page and layout changes alter the data-fetching paradigm significantly; requires validation of Suspense boundaries and state management

Areas requiring extra attention:

  • src/trpc/client.tsx: Singleton query client creation logic and provider composition safety
  • src/app/page.tsx: Transition from server-side data fetch to prefetch/dehydration pattern; verify Suspense boundary placement
  • src/trpc/server.tsx: React cache usage and per-request isolation guarantees in Next.js server context

Poem

🐰 Hops of tRPC, queries take flight,
Server prefetches with QueryCache might,
Dehydrate, hydrate, suspense in the frame,
React Query and TRPC dance—data's their game!
🔗✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'trpc setup' accurately describes the main objective of the pull request, which is to introduce and configure tRPC integration across multiple files including initialization, client setup, routing, and server configuration.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 03--trpc-setup

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai

coderabbitai Bot commented Dec 22, 2025

Copy link
Copy Markdown

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #4

coderabbitai Bot added a commit that referenced this pull request Dec 22, 2025
Docstrings generation was requested by @AMMAR-62.

* #3 (comment)

The following files were modified:

* `src/app/layout.tsx`
* `src/trpc/client.tsx`
* `src/trpc/query-client.ts`

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (7)
src/trpc/routers/_app.ts (1)

4-7: Make the query handler async for clarity.

While tRPC handles Promises automatically, explicitly marking the Prisma query as async improves code clarity and aligns with Prisma best practices.

🔎 Proposed fix
  getUsers: baseProcedure
-    .query(() => {
-      return prisma.user.findMany();
+    .query(async () => {
+      return await prisma.user.findMany();
    }),
src/app/client.tsx (2)

5-5: Remove unused import.

The useState import is not used in this component.

🔎 Proposed fix
-import { useSuspenseQuery } from "@tanstack/react-query";
-import { useState } from "react";
+import { useSuspenseQuery } from "@tanstack/react-query";

7-7: Fix spacing in function declaration.

Add proper spacing around the assignment operator.

🔎 Proposed fix
-export const Client= () => {
+export const Client = () => {
src/trpc/query-client.ts (1)

5-5: Consider enabling superjson for complex data types.

The commented-out superjson setup suggests it may be needed in the future. Without a serializer, complex data types (Date, Map, Set, BigInt, etc.) won't serialize correctly between server and client.

If you need to serialize complex types, install and enable superjson:

npm install superjson

Then uncomment the serialization lines in this file.

Also applies to: 13-13, 19-19

src/app/page.tsx (1)

3-3: Remove unused import.

The caller import is not used in this component.

🔎 Proposed fix
-import { caller, getQueryClient, trpc } from '@/trpc/server'
+import { getQueryClient, trpc } from '@/trpc/server'
src/trpc/init.ts (1)

3-8: Hardcoded userId placeholder needs implementation.

The context currently returns a static userId: 'user_123'. For production, this should integrate with your authentication system (e.g., session, JWT, NextAuth). Additionally, consider accepting request headers to enable proper auth context:

-export const createTRPCContext = cache(async () => {
+export const createTRPCContext = cache(async (opts?: { headers?: Headers }) => {
   /**
    * @see: https://trpc.io/docs/server/context
    */
-  return { userId: 'user_123' };
+  // TODO: Replace with actual auth logic
+  // const session = await getSession(opts?.headers);
+  return { userId: 'user_123' };
 });

Would you like me to open an issue to track implementing proper authentication context?

src/trpc/client.tsx (1)

11-23: Consider adding explicit type for browserQueryClient.

The module-level singleton pattern is correct for preventing query client recreation during React suspense. Adding an explicit type improves clarity:

-let browserQueryClient: QueryClient;
+let browserQueryClient: QueryClient | undefined;

This makes the undefined initial state explicit, which better documents the lazy initialization intent.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0cbbcac and c972106.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • package.json
  • src/app/api/trpc/[trpc]/route.ts
  • src/app/client.tsx
  • src/app/layout.tsx
  • src/app/page.tsx
  • src/trpc/client.tsx
  • src/trpc/init.ts
  • src/trpc/query-client.ts
  • src/trpc/routers/_app.ts
  • src/trpc/server.tsx
🧰 Additional context used
🧬 Code graph analysis (8)
src/trpc/routers/_app.ts (1)
src/trpc/init.ts (2)
  • createTRPCRouter (20-20)
  • baseProcedure (22-22)
src/trpc/server.tsx (4)
src/trpc/query-client.ts (1)
  • makeQueryClient (6-23)
src/trpc/client.tsx (1)
  • createTRPCContext (10-10)
src/trpc/init.ts (1)
  • createTRPCContext (3-8)
src/trpc/routers/_app.ts (1)
  • appRouter (3-8)
src/app/client.tsx (1)
src/trpc/server.tsx (1)
  • trpc (10-14)
src/trpc/init.ts (1)
src/trpc/client.tsx (1)
  • createTRPCContext (10-10)
src/trpc/client.tsx (4)
src/trpc/init.ts (1)
  • createTRPCContext (3-8)
src/trpc/routers/_app.ts (1)
  • AppRouter (10-10)
src/trpc/server.tsx (1)
  • getQueryClient (9-9)
src/trpc/query-client.ts (1)
  • makeQueryClient (6-23)
src/app/layout.tsx (1)
src/trpc/client.tsx (1)
  • TRPCReactProvider (32-59)
src/app/page.tsx (3)
src/trpc/server.tsx (2)
  • getQueryClient (9-9)
  • trpc (10-14)
src/lib/utils.ts (1)
  • cn (4-6)
src/app/client.tsx (1)
  • Client (7-16)
src/app/api/trpc/[trpc]/route.ts (3)
src/trpc/routers/_app.ts (1)
  • appRouter (3-8)
src/trpc/client.tsx (1)
  • createTRPCContext (10-10)
src/trpc/init.ts (1)
  • createTRPCContext (3-8)
🔇 Additional comments (7)
src/app/layout.tsx (1)

4-4: LGTM! Clean tRPC provider integration.

The TRPCReactProvider wrapper is correctly placed in the root layout to provide tRPC context throughout the application.

Also applies to: 31-31

src/app/api/trpc/[trpc]/route.ts (1)

1-11: LGTM! Standard tRPC route handler setup.

The fetch adapter is correctly configured with the router and context creator, and properly exported for both GET and POST requests.

src/app/page.tsx (1)

10-20: LGTM! Correct SSR hydration pattern.

The prefetch + HydrationBoundary + Suspense setup follows React Query and tRPC best practices for server-side rendering with client-side hydration.

package.json (1)

42-45: Dependency versions are compatible.

The tRPC packages (v11.8.1) and @tanstack/react-query (v5.90.12) are compatible with React 19 and Next.js 15, with no known compatibility issues.

src/trpc/init.ts (1)

13-22: LGTM - tRPC initialization follows recommended patterns.

The setup correctly:

  • Avoids exporting the raw t object (as noted in comments)
  • Exposes granular helpers (createTRPCRouter, createCallerFactory, baseProcedure)
  • Leaves room for adding a data transformer when needed
src/trpc/client.tsx (2)

32-59: LGTM - Provider setup follows tRPC + React Query best practices.

The implementation correctly:

  • Uses useState for stable tRPC client reference (preventing recreation on re-renders)
  • Applies the query client singleton pattern with proper SSR handling
  • Nests providers in the correct order (QueryClientProviderTRPCProvider)
  • Includes helpful comments explaining the suspense boundary considerations

24-31: No refactoring is needed. The getUrl() function is client-specific and handles SSR scenarios; src/trpc/server.tsx uses server-side routing via appRouter.createCaller() and does not duplicate this logic.

Likely an incorrect or invalid review comment.

Comment thread src/trpc/server.tsx
@AMMAR-62
AMMAR-62 merged commit 4185b5e into main Dec 22, 2025
1 check passed
@coderabbitai coderabbitai Bot mentioned this pull request Dec 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant