Next.js Discord

Discord Forum

How to Include Clerk Auth Headers in Server-side Fetch

Unanswered
Giant Angora posted this in #help-forum
Open in Discord
Avatar
Giant AngoraOP
I’m using Next.js (App Router) with TanStack Query for prefetching data in a Server Component, and I’m also using Clerk for authentication.

The issue is that when I fetch data from my protected API route inside a Server Component, the request doesn’t include authentication headers automatically. However, when I make the API route public, everything works fine.

Here’s my setup:

🔹 What I’m Doing
- Prefetching data on the server using queryClient.prefetchQuery().
- Fetching from a protected API route that requires authentication.
- Using Clerk for authentication.
🔹 Issue
- Server-side fetch does not include the Clerk session (JWT or cookies).
- The API route rejects the request due to missing authentication.
- If I remove authentication (make the route public), it works fine.

export default async function ProductsPage(props: ProductsPageProps) {
  const { name } = await props.searchParams;

  const isFiltered = !!name;

  const queryClient = getQueryClient();

  void queryClient.prefetchQuery(productsOptions);

  return (
    <HydrationBoundary state={dehydrate(queryClient)}>
      <main className="p-5 md:px-8">
        <div className="mb-5 flex gap-3">
          <DataTableHeading
            heading="Products"
            queryKey={queryKeys.PRODUCTS}
          />
        </div>

        <SwrDataTable
          columns={columns}
          queryKey={queryKeys.PRODUCTS}
          route="products"
          isFiltered={isFiltered}
        />
      </main>
    </HydrationBoundary>
  );
}

11 Replies

Avatar
this is wrong
you don't fetch your own api routes in server components
Avatar
Giant AngoraOP
yeah i know
clerk provides a server side function which you can use to check current auth status and directly query db
Avatar
Giant AngoraOP
i know i can directly query db... but how can i make it work with tanstack query
i use drizzle and fetch directly in server component... what this method arise problem is that when i refresh route with router.refresh, i cannot show any loading indicator
i decided to use tanstack query
Avatar
Giant AngoraOP
i made it work bro
export const PreloadSwrDataTable = <TData extends { id: number }>(
  props: PreloadSwrDataTableProps<TData>,
) => {
  const { columns, isFiltered, promise, queryKey, route } = props;

  const queryClient = getQueryClient();

  return (
    <React.Suspense
      fallback={
        <div className="border-t border-border py-10">
          <Loader2Icon
            size={50}
            className="mx-auto animate-spin text-muted-foreground"
          />
        </div>
      }
    >
      <Awaited promise={promise}>
        {() => (
          <HydrationBoundary state={dehydrate(queryClient)}>
            <SwrDataTable
              columns={columns}
              queryKey={queryKey}
              route={route}
              isFiltered={isFiltered}
            />
          </HydrationBoundary>
        )}
      </Awaited>
    </React.Suspense>
  );
};
i fetched directly instead of using own api route