{
  "id": "ai-puts-server-code-in-client-components",
  "type": "failures",
  "category": "failures",
  "locale": "de",
  "url": "/de/failures/ai-puts-server-code-in-client-components",
  "title": "So beheben Sie, dass KI Server-Code in Client-Komponenten platziert",
  "description": "KI-Agenten geben Datenbankabfragen, geheime Umgebungsvariablen und Node.js-APIs in `'use client'`-Komponenten preis, wodurch serverseitige Logik im Browser-Bundle offengelegt wird.",
  "tools": [
    "Cursor",
    "Claude Code",
    "Codex",
    "Windsurf"
  ],
  "stack": [
    "Next.js",
    "TypeScript"
  ],
  "tags": [
    "nextjs",
    "security",
    "react"
  ],
  "difficulty": null,
  "updated": "2026-06-08",
  "markdown": "Der Agent fügt eine `\"use client\"`-Direktive zu einer Komponente hinzu, die Prisma,\n`fs` oder eine geheime Umgebungsvariable importiert – was diesen Code in das Browser-Bundle jedes Besuchers packt.\n\n## Das Symptom\n\nEine Komponente, die als `\"use client\"` markiert ist, führt einen direkten Datenbankaufruf durch oder liest ein\n`process.env`-Geheimnis.\n\n```tsx\n\"use client\";\nimport { db } from \"@/lib/db\"; // Prisma client — Node.js only\nimport { useState, useEffect } from \"react\";\n\nexport function UserCard({ id }: { id: string }) {\n  const [user, setUser] = useState(null);\n\n  useEffect(() => {\n    // db is a Node.js module — this will throw at runtime in the browser\n    db.user.findUnique({ where: { id } }).then(setUser);\n  }, [id]);\n\n  return <div>{user?.name}</div>;\n}\n```\n\nDer Build kann erfolgreich sein (Next.js bündelt den Import), aber die Seite wirft einen Laufzeitfehler im Browser,\nweil `@prisma/client` Node.js-APIs benötigt.\n\n## Warum es passiert\n\nDer 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.\n\n## Wie man es erkennt\n\n- `\"use client\"` am Anfang einer Datei, die auch aus `@/lib/db`,\n  `prisma`, `fs`, `path` oder `crypto` importiert.\n- `process.env.DATABASE_URL` oder eine beliebige `_SECRET_`-Variable, die in einer\n  `\"use client\"`-Datei gelesen wird.\n- Die Build-Ausgabe enthält `Critical dependency: the request of a dependency is\n  an expression` oder eine Prisma-Bundle-Warnung.\n- Das Paket `server-only` fehlt im Projekt.\n\n## Wie man es behebt\n\nTeilen Sie es auf in eine Server-Komponente als Elternkomponente, die abruft, und eine Client-Komponente als Kind,\ndie die Interaktivität übernimmt.\n\n```tsx\n// app/users/[id]/page.tsx — Server Component (no directive)\nimport { db } from \"@/lib/db\";\nimport { UserCard } from \"./UserCard\";\n\nexport default async function UserPage({ params }: { params: { id: string } }) {\n  const user = await db.user.findUniqueOrThrow({ where: { id: params.id } });\n  // Serialize — pass plain data, not the Prisma object\n  return <UserCard name={user.name} email={user.email} />;\n}\n```\n\n```tsx\n// app/users/[id]/UserCard.tsx — Client Component\n\"use client\";\nimport { useState } from \"react\";\n\nexport function UserCard({ name, email }: { name: string; email: string }) {\n  const [expanded, setExpanded] = useState(false);\n  return (\n    <div>\n      <p>{name}</p>\n      {expanded && <p>{email}</p>}\n      <button onClick={() => setExpanded((v) => !v)}>Toggle</button>\n    </div>\n  );\n}\n```\n\n```txt\n[ ] Install \"server-only\" and import it at the top of every server-side lib file\n[ ] No db/prisma imports in \"use client\" files\n[ ] No process.env secrets read in \"use client\" files\n[ ] Server Component fetches data; Client Component receives plain props\n[ ] Use Server Actions (not useEffect+fetch) when a client interaction needs db access\n```\n\n## Korrektur-Prompt\n\n```txt title=\"Fix Prompt\"\nThis \"use client\" component imports server-only modules (Prisma, fs, or secret\nenv vars). Refactor it: move all data fetching into an async Server Component\nparent, pass only serializable props to the client component, and keep \"use\nclient\" only on the part that needs browser APIs or React state. Add\n\"server-only\" to any shared lib files that must never reach the browser.\n```\n\n## Test\n\n```bash\n# List all \"use client\" files that also import known server-only packages\ngrep -rl '\"use client\"' app/ | xargs grep -l \"prisma\\|@/lib/db\\|\\\"fs\\\"\\|\\\"path\\\"\\|\\\"crypto\\\"\" && echo \"FAIL: server code in client component\" || echo \"OK\"\n```"
}