T
TanStack4mo ago
wee-brown

prevent db module going to client

I'm trying to execute a db query on my route loader, but my db file imports "server-only" and I'm getting this error
This module cannot be imported from a Client Component module. It should only be used from a Server Component.
This module cannot be imported from a Client Component module. It should only be used from a Server Component.
this is my route:
import { createFileRoute } from "@tanstack/react-router";
import { db } from "@/db";
import { eventsTable } from "@/db/schema";

export const Route = createFileRoute("/events/")({
component: RouteComponent,
loader: async () => {
const events = await db.select().from(eventsTable).execute();
return { events };
},
});

function RouteComponent() {
const { events } = Route.useLoaderData();
return (
<div>
<h1>Events</h1>
{events.map((event) => (
<div key={event.id}>{event.name}</div>
))}
</div>
);
}
import { createFileRoute } from "@tanstack/react-router";
import { db } from "@/db";
import { eventsTable } from "@/db/schema";

export const Route = createFileRoute("/events/")({
component: RouteComponent,
loader: async () => {
const events = await db.select().from(eventsTable).execute();
return { events };
},
});

function RouteComponent() {
const { events } = Route.useLoaderData();
return (
<div>
<h1>Events</h1>
{events.map((event) => (
<div key={event.id}>{event.name}</div>
))}
</div>
);
}
how can I prevent my db module from going to the client
8 Replies
fascinating-indigo
fascinating-indigo4mo ago
Use createServerFn for the query and call the function from your loader
wee-brown
wee-brownOP4mo ago
still having the same issue. is this right?
import { createFileRoute } from "@tanstack/react-router";
import { createServerFn } from "@tanstack/react-start";
import { db } from "@/db";
import { eventsTable } from "@/db/schema";

const getEvents = createServerFn().handler(async () => {
const events = await db.select().from(eventsTable).execute();
return events;
});

export const Route = createFileRoute("/events/")({
component: RouteComponent,
loader: async () => {
const events = await getEvents();
return { events };
},
});

function RouteComponent() {
const { events } = Route.useLoaderData();
return (
<div>
<h1>Events</h1>
{events.map((event) => (
<div key={event.id}>{event.name}</div>
))}
</div>
);
}
import { createFileRoute } from "@tanstack/react-router";
import { createServerFn } from "@tanstack/react-start";
import { db } from "@/db";
import { eventsTable } from "@/db/schema";

const getEvents = createServerFn().handler(async () => {
const events = await db.select().from(eventsTable).execute();
return events;
});

export const Route = createFileRoute("/events/")({
component: RouteComponent,
loader: async () => {
const events = await getEvents();
return { events };
},
});

function RouteComponent() {
const { events } = Route.useLoaderData();
return (
<div>
<h1>Events</h1>
{events.map((event) => (
<div key={event.id}>{event.name}</div>
))}
</div>
);
}
fascinating-indigo
fascinating-indigo4mo ago
That looks right. Are you doing this multiple places? Try restarting dev server also
wee-brown
wee-brownOP4mo ago
no, this is the only route I have. just setup the project. this is my db file
import "server-only";
import { drizzle } from "drizzle-orm/node-postgres";
import { env } from "@/schemas/env";
import * as schema from "./schema";

export const db = drizzle(env.DATABASE_URL, { schema });
import "server-only";
import { drizzle } from "drizzle-orm/node-postgres";
import { env } from "@/schemas/env";
import * as schema from "./schema";

export const db = drizzle(env.DATABASE_URL, { schema });
issue persists after restarting the dev server am I missing something?
genetic-orange
genetic-orange4mo ago
the problem is "server-only" dont import it this is not supported
wee-brown
wee-brownOP4mo ago
ohh okay, it works now! I'm using it because I didn't had the db in a server function before, so drizzle was getting some missing modules since it was running on the client shouldn't all code inside "loader" be exclusive to the server since it only runs there?
genetic-orange
genetic-orange4mo ago
no loaders are isomorphic, that means they run on the server for the SSR request and then on the client for each subsequent navigations
wee-brown
wee-brownOP4mo ago
oh okay, it makes sense! thanks!

Did you find this page helpful?