T
tRPC
TRPC with Nextjs 13 App Router
TRPC with Nextjs 13 App Router
Im trying to implement TRPC with my already existing Nextjs 13 App to get typesafe API's. I've managed to get it to work in Client Components, meaning i can make the API Calls from them but whenever I try to use them on a server rendered Page, I keep getting an error. In the tutorials I followed, it worked perfectly fine in the Server Rendered Page so I'm wondering how to fix this.
Related Files:
Here is the Error i get:
You're importing a component that needs useEffect. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
╭─[@trpc+react-query@10.43.0@tanstack+react-query@4.36.1@trpc+client@10.43.0_@trpc+server@10.4_7lsmxlrq3xi3juoktsh4534bt4\node_modules@trpc\react-query\dist\createHooksInternal-bdff7171.mjs:2:1]
4 │ import { useQuery, useQueryClient, useMutation, hashQueryKey, useInfiniteQuery, useQueries } from '@tanstack/react-query';
5 │ import React, { createContext, useRef, useState, useEffect, useCallback, useMemo } from 'react';
· ─────────
6 │
7 │ /**
8 │ * We treat
layout.tsx:
import "./globals.css";
import { Inter } from "next/font/google";
import { ThemeProvider } from "@/src/app/components/providers/ThemeProvider";
import Providers from "./_trpc/Providers";
const inter = Inter({ subsets: ["latin"] });
export const metadata = {
title: "",
description: "",
};
function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<Providers>
<body className={inter.className}>
<ThemeProvider attribute="class" defaultTheme="light">
{children}
</ThemeProvider>
</body>
</Providers>
</html>
);
}
export default RootLayout;
-------
client.ts
import { AppRouter } from "@/src/server";
import { createTRPCReact } from "@trpc/react-query";
export const trpc = createTRPCReact<AppRouter>({});
--------
Providers.tsx
"use client";
import { trpc } from "@/src/app/_trpc/client";
import { absoluteUrl } from "@/lib/utils";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { httpBatchLink } from "@trpc/client";
import { PropsWithChildren, useState } from "react";
const Providers = ({ children }: PropsWithChildren) => {
const [queryClient] = useState(() => new QueryClient());
const [trpcClient] = useState(() =>
trpc.createClient({
links: [
httpBatchLink({
url: absoluteUrl("/api/trpc"),
}),
],
})
);
return (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</trpc.Provider>
);
};
export default Providers;
-----
page.tsx
import PostList from "./components/ui/PostList";
import { getCurrentUser } from "@/lib/session";
import Navbar from "./components/sections/Navbar";
import { fetchPosts } from "@/lib/actions/post.actions";
import BottomNavbar from "./components/sections/BottomNavbar";
import Temp from "./components/Temp";
import { trpc } from "./_trpc/client";
const Home = async () => {
const user = await getCurrentUser();
const posts = await fetchPosts();
const { data } = trpc.posts.getMany.useQuery();
return (
<div>
<Navbar user={user} />
<Temp />
<div className="px-4 pt-2 mx-auto max-w-[1245px]">
<PostList posts={posts} userId={user?.id} />
</div>
<BottomNavbar user={user} />
</div>
);
};
export default Home;
layout.tsx:
import "./globals.css";
import { Inter } from "next/font/google";
import { ThemeProvider } from "@/src/app/components/providers/ThemeProvider";
import Providers from "./_trpc/Providers";
const inter = Inter({ subsets: ["latin"] });
export const metadata = {
title: "",
description: "",
};
function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<Providers>
<body className={inter.className}>
<ThemeProvider attribute="class" defaultTheme="light">
{children}
</ThemeProvider>
</body>
</Providers>
</html>
);
}
export default RootLayout;
-------
client.ts
import { AppRouter } from "@/src/server";
import { createTRPCReact } from "@trpc/react-query";
export const trpc = createTRPCReact<AppRouter>({});
--------
Providers.tsx
"use client";
import { trpc } from "@/src/app/_trpc/client";
import { absoluteUrl } from "@/lib/utils";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { httpBatchLink } from "@trpc/client";
import { PropsWithChildren, useState } from "react";
const Providers = ({ children }: PropsWithChildren) => {
const [queryClient] = useState(() => new QueryClient());
const [trpcClient] = useState(() =>
trpc.createClient({
links: [
httpBatchLink({
url: absoluteUrl("/api/trpc"),
}),
],
})
);
return (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</trpc.Provider>
);
};
export default Providers;
-----
page.tsx
import PostList from "./components/ui/PostList";
import { getCurrentUser } from "@/lib/session";
import Navbar from "./components/sections/Navbar";
import { fetchPosts } from "@/lib/actions/post.actions";
import BottomNavbar from "./components/sections/BottomNavbar";
import Temp from "./components/Temp";
import { trpc } from "./_trpc/client";
const Home = async () => {
const user = await getCurrentUser();
const posts = await fetchPosts();
const { data } = trpc.posts.getMany.useQuery();
return (
<div>
<Navbar user={user} />
<Temp />
<div className="px-4 pt-2 mx-auto max-w-[1245px]">
<PostList posts={posts} userId={user?.id} />
</div>
<BottomNavbar user={user} />
</div>
);
};
export default Home;
undefined
as an input the same as omitting an input
╰────
Maybe one of these should be marked as a client entry with "use client":
./src\app_trpc\client.ts
./src\app\page.tsxWithout knowing the context, my assumption is that you're using the
api
exported from app_trpc/client.ts
in the app/page.tsx, which is a page without the use client directive.
If you're using a mutation in a form
(or similar), simply move that form into it's own component (separate from the page.tsx
) and add "use client"
in the first line of the file. Then import your NewForm
component from page.tsx
and this error should go away.Looking for more? Join the community!
T
tRPC
TRPC with Nextjs 13 App Router
T
tRPC
TRPC with Nextjs 13 App Router
Recommended Posts
Security: DDOS attack prevention for open endpoints tRPCSo we are building an application and got multiple trpc endpoints associated with it, some of them aIs there any information about caching in `@trpc/react-query`?How does query caching work? I want to create library for Angular and I would like to understand Reacache craziness?can someone sanity check something for me? i'm using sst + trpc + drizzleorm + aws + rds + postgretRPC over WebSocket with Next.js and NextAuthHi. I'm trying to set up Next 13 with tRPC over a WebSocket and NextAuth. I got it mostly working wi