P PasteCode
Fehlschlag

So beheben Sie, dass KI Server-Code in Client-Komponenten platziert

KI-Agenten geben Datenbankabfragen, geheime Umgebungsvariablen und Node.js-APIs in `'use client'`-Komponenten preis, wodurch serverseitige Logik im Browser-Bundle offengelegt wird.

CursorClaude CodeCodexWindsurf Next.jsTypeScript
.md .json Aktualisiert 8. Juni 2026

Der Agent fügt eine "use client"-Direktive zu einer Komponente hinzu, die Prisma, fs oder eine geheime Umgebungsvariable importiert – was diesen Code in das Browser-Bundle jedes Besuchers packt.

Das Symptom

Eine Komponente, die als "use client" markiert ist, führt einen direkten Datenbankaufruf durch oder liest ein process.env-Geheimnis.

"use client";
import { db } from "@/lib/db"; // Prisma client — Node.js only
import { useState, useEffect } from "react";
export function UserCard({ id }: { id: string }) {
const [user, setUser] = useState(null);
useEffect(() => {
// db is a Node.js module — this will throw at runtime in the browser
db.user.findUnique({ where: { id } }).then(setUser);
}, [id]);
return <div>{user?.name}</div>;
}

Der Build kann erfolgreich sein (Next.js bündelt den Import), aber die Seite wirft einen Laufzeitfehler im Browser, weil @prisma/client Node.js-APIs benötigt.

Warum es passiert

Der Agent erkennt, dass Daten in einer Komponente benötigt werden, die auch State oder Effekte verwendet, und greift auf die ihm bekannte Datenebene zu. Er modelliert nicht die Server/Client-Grenze und weiß nicht, dass "use client"-Komponenten keine Node.js-exklusiven Module importieren können.

Wie man es erkennt

  • "use client" am Anfang einer Datei, die auch aus @/lib/db, prisma, fs, path oder crypto importiert.
  • process.env.DATABASE_URL oder eine beliebige _SECRET_-Variable, die in einer "use client"-Datei gelesen wird.
  • Die Build-Ausgabe enthält Critical dependency: the request of a dependency is an expression oder eine Prisma-Bundle-Warnung.
  • Das Paket server-only fehlt im Projekt.

Wie man es behebt

Teilen Sie es auf in eine Server-Komponente als Elternkomponente, die abruft, und eine Client-Komponente als Kind, die die Interaktivität übernimmt.

// app/users/[id]/page.tsx — Server Component (no directive)
import { db } from "@/lib/db";
import { UserCard } from "./UserCard";
export default async function UserPage({ params }: { params: { id: string } }) {
const user = await db.user.findUniqueOrThrow({ where: { id: params.id } });
// Serialize — pass plain data, not the Prisma object
return <UserCard name={user.name} email={user.email} />;
}
// app/users/[id]/UserCard.tsx — Client Component
"use client";
import { useState } from "react";
export function UserCard({ name, email }: { name: string; email: string }) {
const [expanded, setExpanded] = useState(false);
return (
<div>
<p>{name}</p>
{expanded && <p>{email}</p>}
<button onClick={() => setExpanded((v) => !v)}>Toggle</button>
</div>
);
}
[ ] Install "server-only" and import it at the top of every server-side lib file
[ ] No db/prisma imports in "use client" files
[ ] No process.env secrets read in "use client" files
[ ] Server Component fetches data; Client Component receives plain props
[ ] Use Server Actions (not useEffect+fetch) when a client interaction needs db access

Korrektur-Prompt

Fix Prompt
This "use client" component imports server-only modules (Prisma, fs, or secret
env vars). Refactor it: move all data fetching into an async Server Component
parent, pass only serializable props to the client component, and keep "use
client" only on the part that needs browser APIs or React state. Add
"server-only" to any shared lib files that must never reach the browser.

Test

Terminal window
# List all "use client" files that also import known server-only packages
grep -rl '"use client"' app/ | xargs grep -l "prisma\|@/lib/db\|\"fs\"\|\"path\"\|\"crypto\"" && echo "FAIL: server code in client component" || echo "OK"