next.jsclerkdrizzlehono

Next JS server Component fetch data when using clerk for authentication and Hono js For backend


I am using next JS server component to fetch data with search params using clerk authentication package. Also, using hono JS as backend with drizzle ORM.

The issue is can't fetch data in server component as clerk does not sending auth session or token in from server component when doing it on it's own for client component.

import { UserNav } from "@/components/data-table/user-nav";
import { searchParamsSchema } from "@/db/validations";
import { client } from "@/lib/hono";
import TaskUi from "@/view/tasks/TaskUi";
import { auth } from "@clerk/nextjs/server";

type Props = {
    searchParams: Record<string, string>;
};

export const revalidate = 0;

export default async function TaskPage({ searchParams }: Props) {
    const search = searchParamsSchema.parse(searchParams);
    const { getToken } = auth();

    const token = await getToken();
    console.log("🚀 ~ TaskPage ~ token:", token);
    const response = await client.api.tasks.$get({
        query: search,
        headers: { Authorization: `Bearer ${token}` },
    });

    console.log("🚀 ~ response headers:", response.headers);

    if (!response.ok) {
        throw new Error("Error fetching tasks");
    }

    const initialData = await response.json();

    return (
        <>
            <div className="h-full flex-1 flex-col space-y-8 p-8 md:flex">
                <div className="flex items-center justify-between space-y-2">
                    <div>
                        <h2 className="text-2xl font-bold tracking-tight">Welcome back!</h2>
                        <p className="text-muted-foreground">Here&apos;s a list of your tasks for this month!</p>
                    </div>
                    <div className="flex items-center space-x-2">
                        <UserNav />
                    </div>
                </div>
                <TaskUi initialData={initialData} search={search} />
            </div>
        </>
    );
}

console in terminal:

🚀 ~ response headers: Headers {
  'x-clerk-auth-reason': 'dev-browser-missing',
  'x-clerk-auth-status': 'signed-out',
  'x-middleware-rewrite': '/api/tasks?page=1&per_page=10',
  'content-type': 'application/json; charset=UTF-8',
  date: 'Wed, 02 Oct 2024 06:46:45 GMT',
  connection: 'keep-alive',
  'keep-alive': 'timeout=5',
  'transfer-encoding': 'chunked'
}

backend code:

const app = new Hono()
    .use("*", clerkMiddleware())
    .get("/", async (ctx) => {
        const query = ctx.req.query();
        const parsedParams = getTasksSchema.safeParse(query);
        const auth = getAuth(ctx);

        if (!auth?.userId) {
            return ctx.json({ error: "Unauthorized" }, 401);
        }

        if (!parsedParams.success) {
            return ctx.json({ error: "Invalid query params" }, 400);
        }

........
........

        return ctx.json({
            data,
            meta: {
                page,
                pageCount,
                total,
            },
        });
    })

facing error:

 ⨯ Error: Error fetching tasks
    at TaskPage (D:\Workspace\2. Projects\company-website\.next\server\chunks\ssr\_935b95._.js:1232:15)
digest: "3934253529"
 ⨯ Error: Error fetching tasks
    at TaskPage (D:\Workspace\2. Projects\company-website\.next\server\chunks\ssr\_935b95._.js:1232:15)
digest: "3934253529"

can fetch data if I remove clerkMiddleware(), and userId check console.log("🚀 ~ TaskPage ~ token:", token); Also can fetch data with that token as bearer from postman

Why could not doing same in server component !!! help pls.


Solution

  • Okay after go through hono RPC guides I get the solution I have to send headers in another object like bellow :

    const response = await client.api.tasks.$get(
            { query: search },
            {
                headers: { Authorization: `Bearer ${token}` },
            },
        );
    

    or I can directly use fetch also

    const response = await fetch("http://localhost:3000/api/tasks", {
            method: "GET",
            headers: {
                Authorization: `Bearer ${token}`,
            },
        });