tRPCttRPC
Powered by
LopaisL
tRPC•7mo ago
Lopais

tRPC + Nextjs: redirect on next error with new TanStack Query integration

Using a tRPC middleware like this that throws a Nextjs error:

export const withSessionProcedure = t.procedure
  .use(timingMiddleware)
  .use(({ next, ctx: { session, ...rest } }) => {
    if (!session) {
      redirect($path({ route: "/sign-in" }));
    }

    return next({
      ctx: { session, ...rest },
    });
  });
export const withSessionProcedure = t.procedure
  .use(timingMiddleware)
  .use(({ next, ctx: { session, ...rest } }) => {
    if (!session) {
      redirect($path({ route: "/sign-in" }));
    }

    return next({
      ctx: { session, ...rest },
    });
  });


I had a working SSR setup with the old TanStack Query integration, where error / redirect is handled directly the API was called:

export const api = createCallerFactory(appRouter)(createContext, {
  onError({ error }) {
    // this handled the "redirect" error above
    unstable_rethrow(error);
    throw error;
  },
});
export const api = createCallerFactory(appRouter)(createContext, {
  onError({ error }) {
    // this handled the "redirect" error above
    unstable_rethrow(error);
    throw error;
  },
});


Migrating over to the new tanstack query integration, I now perform tRPC calls during SSR with a queryClient:

export const createQueryClient = () =>
  new QueryClient({
    defaultOptions: {
      queries: {
        staleTime: 30 * 1000,
      },
      dehydrate: {
        serializeData: SuperJSON.serialize,
        shouldDehydrateQuery: (query) =>
          defaultShouldDehydrateQuery(query) ||
          query.state.status === "pending",
      },
      hydrate: {
        deserializeData: SuperJSON.deserialize,
      },
    },
  });

export const getQueryClient = cache(createQueryClient);
export const createQueryClient = () =>
  new QueryClient({
    defaultOptions: {
      queries: {
        staleTime: 30 * 1000,
      },
      dehydrate: {
        serializeData: SuperJSON.serialize,
        shouldDehydrateQuery: (query) =>
          defaultShouldDehydrateQuery(query) ||
          query.state.status === "pending",
      },
      hydrate: {
        deserializeData: SuperJSON.deserialize,
      },
    },
  });

export const getQueryClient = cache(createQueryClient);


page.tsx:
import { getQueryClient, HydrateClient, trpc } from "@/trpc/server";

import { StaffView } from "./view";

export default async function StaffPage() {
  const queryClient = getQueryClient();

  await queryClient.prefetchQuery(trpc.staff.general.list.queryOptions());

  return (
    <HydrateClient>
      <StaffView />
    </HydrateClient>
  );
}
import { getQueryClient, HydrateClient, trpc } from "@/trpc/server";

import { StaffView } from "./view";

export default async function StaffPage() {
  const queryClient = getQueryClient();

  await queryClient.prefetchQuery(trpc.staff.general.list.queryOptions());

  return (
    <HydrateClient>
      <StaffView />
    </HydrateClient>
  );
}


This just throws a "TRPCError: NEXT_REDIRECT" now though.

I am looking to get back the functionality I had with the old TanStack Query integration, but can't find where to catch and handle the error before it throws on the queryClient using the new integration.
tRPCJoin
Move Fast & Break Nothing. End-to-end typesafe APIs made easy.
5,015Members
Resources

Similar Threads

Was this page helpful?
Recent Announcements

Similar Threads

error: NEXT_REDIRECT
XavierBreadXXavierBread / ❓-help
2y ago
How to handle TRPC error with tanstack/query in components
corvonotgayCcorvonotgay / ❓-help
17mo ago