Skip to content

fix: add guide to embed Prisma Studio in Next.js - #7079

Merged
ankur-arch merged 8 commits into
mainfrom
DC-4813
Aug 21, 2025
Merged

fix: add guide to embed Prisma Studio in Next.js#7079
ankur-arch merged 8 commits into
mainfrom
DC-4813

Conversation

@ankur-arch

@ankur-arch ankur-arch commented Aug 19, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Studio UI accepts an optional theme string prop for custom theming.
  • Documentation

    • Added a full Next.js embedding guide (embed-studio-nextjs) with end-to-end setup, API bridge, runtime flow, testing, production guidance, and licensing notes.
    • Examples updated to import required UI CSS and demonstrate custom theming and header/auth usage.
    • Backend examples now show a server-oriented Postgres executor using DATABASE_URL; sidebar navigation updated to include the new guide.
  • Bug Fixes

    • Fixed typos and clarified authentication/authorization wording.

@ankur-arch ankur-arch self-assigned this Aug 19, 2025
@coderabbitai

coderabbitai Bot commented Aug 19, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds documentation and examples for embedding Prisma Studio: introduces a theme prop and custom styling, updates executor/server examples to use createPrismaPostgresHttpClient with DATABASE_URL, adds a new Next.js embedding guide with an /api/studio bridge, and adds the guide to the sidebar.

Changes

Cohort / File(s) Summary
Studio docs: embedding & styling
content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx
Reworded embedding intro; replaced API-key backend narrative with createPrismaPostgresHttpClient using DATABASE_URL; added “Custom styling” section and documents optional theme (string) prop for Studio; added import "@prisma/studio-core/ui/index.css" to examples; fixed typos; updated frontend auth wording and demo server references.
New Next.js guide (end-to-end)
content/800-guides/360-embed-studio-nextjs.mdx
New guide: full Next.js embedding flow with prerequisites, Prisma/Postgres setup, schema seeding, dynamic Studio import (ssr: false), StudioWrapper, adapter/executor wiring, and a backend API route at app/api/studio/route.ts (GET health, POST execute, OPTIONS/CORS) using createPrismaPostgresHttpClient.
Sidebar update
sidebars.ts
Adds guides/embed-studio-nextjs to Integration Solutions items array (appended and sorted); no type/signature changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Client as Next.js client
  participant Studio as Studio UI (ssr: false)
  participant API as /api/studio (Route)
  participant PrismaHTTP as createPrismaPostgresHttpClient
  participant DB as Postgres

  User->>Client: Navigate to page
  Client-->>Studio: Render inside StudioWrapper (Suspense)
  Studio->>API: POST /api/studio { query, auth headers, user }
  API->>API: Validate input & env (DATABASE_URL)
  API->>PrismaHTTP: execute(query)
  PrismaHTTP->>DB: Execute SQL
  DB-->>PrismaHTTP: Results / Error
  PrismaHTTP-->>API: Response / serialized error
  API-->>Studio: JSON { data | serializedError } + CORS headers
  Studio-->>User: Render data or error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

Suggested reviewers

  • mhessdev
  • nurul3101
  • nikolasburk

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch DC-4813

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions

Copy link
Copy Markdown
Contributor

Dangerous URL check

No absolute URLs to prisma.io/docs found.
No local URLs found.

@github-actions

Copy link
Copy Markdown
Contributor

Redirect check

This PR probably requires the following redirects to be added to static/_redirects:

  • This PR does not change any pages in a way that would require a redirect.

@github-actions

Copy link
Copy Markdown
Contributor

Images automagically compressed by Calibre's image-actions

Compression reduced images by 20%, saving 62.63 KB.

Filename Before After Improvement Visual comparison
static/img/guides/prisma-studio-embedded-in-nextjs.png 313.05 KB 250.42 KB -20.0% View diff

208 images did not require optimisation.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 19, 2025

Copy link
Copy Markdown

Deploying docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 481de1b
Status: ✅  Deploy successful!
Preview URL: https://251895f0.docs-51g.pages.dev
Branch Preview URL: https://dc-4813.docs-51g.pages.dev

View logs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx (3)

183-186: Function reference mismatch: Accelerate vs Prisma Postgres client.

The text mentions createAccelerateHttpClient, but examples below use createPrismaPostgresHttpClient. Update the wording (or add the Accelerate variant as a separate example).

-Your backend needs to expose a `/studio` endpoint, that's where the frontend sends its requests. The implementation of this endpoint uses the `createAccelerateHttpClient` function that can be imported from the `@prisma/studio-core`.
+Your backend needs to expose a `/studio` endpoint where the frontend sends its requests. The implementation below uses `createPrismaPostgresHttpClient` from `@prisma/studio-core`. (You can also build an Accelerate-based variant with the corresponding client if needed.)

193-200: Missing import for CORS middleware in Hono example.

The example uses cors() but doesn’t import it. Add the import to prevent runtime errors.

 import { Hono } from "hono";
+import { cors } from "hono/cors";
 import { createPrismaPostgresHttpClient } from "@prisma/studio-core/data/ppg";
 import { serializeError } from "@prisma/studio-core/data/bff";
 
 const app = new Hono().use("*", cors());

224-232: Missing import for CORS middleware in the advanced Hono example as well.

Same fix applies to the second snippet.

 // server/index.ts
 import { Hono } from "hono";
+import { cors } from "hono/cors";
 import { createPrismaPostgresHttpClient } from "@prisma/studio-core/data/ppg";
 import { serializeError } from "@prisma/studio-core/data/bff";
 
 const app = new Hono().use("*", cors());
🧹 Nitpick comments (5)
content/800-guides/360-embed-studio-nextjs.mdx (3)

112-121: Simplify client output path and imports (use default @prisma/client).

Customizing generator.output and importing from app/generated/prisma adds complexity without benefit here. Prefer the default @prisma/client output and import path.

Update schema and seed snippet:

 generator client {
   provider = "prisma-client-js"
-  output   = "../app/generated/prisma"
 }
-import { PrismaClient } from '../app/generated/prisma'
+import { PrismaClient } from '@prisma/client'

Also applies to: 159-160


213-228: JSON with comments: prefer jsonc to avoid invalid JSON in copy-paste.

The code block includes comments, which break strict JSON. If comments are desired for readability, mark the fence as jsonc.

-```json file=package.json
+```jsonc file=package.json
 {
   "name": "nextjs-studio-embed",
   "version": "0.1.0",
   "private": true,
   // add-start
   "prisma": {
     "seed": "tsx prisma/seed.ts"
   },
   // add-end
   "scripts": {
     // ... existing scripts
   }
   // ... rest of package.json
 }

83-85: Unused dependency: @prisma/extension-accelerate is not referenced.

Nothing in this guide uses the extension. Consider dropping it to reduce noise, or add a note explaining why it’s installed.

-npm install @prisma/extension-accelerate @prisma/client
+npm install @prisma/client
content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx (2)

23-26: Tighten grammar in use cases.

Minor clarity/grammar tweaks.

-- Create an quick admin dashboard for editing data
-- Multi-tenant application where every user has their own DB
-- Provide an easy way to view and edit data to your users
+- Create a quick admin dashboard for editing data
+- Build multi-tenant applications where each user has their own database
+- Provide your users with an easy way to view and edit data

270-287: Execution flow comment mentions API key; update to reflect DATABASE_URL.

The (commented) diagram text says “Extract API key”. For consistency with the code samples, reference the connection URL (or tenant-to-URL resolution).

-    Backend->>Backend: Extract API key from request
+    Backend->>Backend: Determine connection URL (e.g., from tenant context)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6fdd154 and db9e3cf.

⛔ Files ignored due to path filters (2)
  • static/img/guides/embedded-studio.gif is excluded by !**/*.gif
  • static/img/guides/prisma-studio-embedded-in-nextjs.png is excluded by !**/*.png
📒 Files selected for processing (3)
  • content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx (5 hunks)
  • content/800-guides/360-embed-studio-nextjs.mdx (1 hunks)
  • sidebars.ts (1 hunks)
🧰 Additional context used
🪛 LanguageTool
content/800-guides/360-embed-studio-nextjs.mdx

[grammar] ~23-~23: There might be a mistake here.
Context: ...a quick admin dashboard for editing data - Supporting multi-tenant applications whe...

(QB_NEW_EN)


[grammar] ~24-~24: There might be a mistake here.
Context: ...s where each user has their own database - Giving users an easy way to view and edi...

(QB_NEW_EN)


[grammar] ~31-~31: There might be a mistake here.
Context: ...pache 2.0. ✔️ Free to use in production ⚠️ Prisma branding must remain visible a...

(QB_NEW_EN)


[grammar] ~33-~33: There might be a mistake here.
Context: ...es, reach out at partnerships@prisma.io Currently, Embedded Prisma Studio support...

(QB_NEW_EN)


[grammar] ~41-~41: There might be a mistake here.
Context: .... ::: ## Prerequisites - Node.js 18+ - Basic knowledge of React and Next.js - A...

(QB_NEW_EN)


[grammar] ~42-~42: There might be a mistake here.
Context: ...) - Basic knowledge of React and Next.js - A Prisma Postgres database ## 1. Setti...

(QB_NEW_EN)


[style] ~53-~53: Consider removing “of” to be more concise
Context: ...ew questions about your project. Select all of the defaults. :::info For reference, thos...

(ALL_OF_THE)


[grammar] ~59-~59: There might be a mistake here.
Context: ... For reference, those are: - TypeScript - ESLint - Tailwind CSS - No src directo...

(QB_NEW_EN)


[grammar] ~60-~60: There might be a mistake here.
Context: ...rence, those are: - TypeScript - ESLint - Tailwind CSS - No src directory - App ...

(QB_NEW_EN)


[grammar] ~61-~61: There might be a mistake here.
Context: ...e: - TypeScript - ESLint - Tailwind CSS - No src directory - App Router - Turbop...

(QB_NEW_EN)


[grammar] ~62-~62: There might be a mistake here.
Context: ...Lint - Tailwind CSS - No src directory - App Router - Turbopack - Select default ...

(QB_NEW_EN)


[grammar] ~63-~63: There might be a mistake here.
Context: ...nd CSS - No src directory - App Router - Turbopack - Select default import alias ...

(QB_NEW_EN)


[grammar] ~64-~64: There might be a mistake here.
Context: ...src directory - App Router - Turbopack - Select default import alias ::: Then, ...

(QB_NEW_EN)


[grammar] ~102-~102: There might be a mistake here.
Context: ...directory with your schema.prisma file - A new Prisma Postgres database - A `.env...

(QB_NEW_EN)


[grammar] ~103-~103: There might be a mistake here.
Context: ...afile - A new Prisma Postgres database - A.envfile with yourDATABASE_URL` -...

(QB_NEW_EN)


[grammar] ~104-~104: There might be a mistake here.
Context: ...gres database - A .env file with your DATABASE_URL - An output directory at `app/generated/pr...

(QB_NEW_EN)


[style] ~292-~292: Consider a more expressive alternative.
Context: ...s (or errors) back to the frontend. To do this, create a new folder called api ...

(DO_ACHIEVE)


[grammar] ~433-~433: There might be a mistake here.
Context: ...uld appear. 3. Interactive features: - Browse and filter records in your tables...

(QB_NEW_EN)


[style] ~436-~436: ‘new records’ might be wordy. Consider a shorter alternative.
Context: ...nline by double-clicking cells - Add new records using the "Add record" button - Dele...

(EN_WORDINESS_PREMIUM_NEW_RECORDS)


[style] ~444-~444: ‘new record’ might be wordy. Consider a shorter alternative.
Context: ...o check that changes are saved. - Add a new record and confirm it appears instantly. - Try...

(EN_WORDINESS_PREMIUM_NEW_RECORD)

🔇 Additional comments (2)
sidebars.ts (1)

451-452: Sidebar entry looks correct; alphabetical sort will place it properly.

The new "guides/embed-studio-nextjs" item is consistent with existing IDs and will be alphabetically sorted within “Integration Solutions”.

If you want to double-check the doc id, ensure the frontmatter or path resolves to "guides/embed-studio-nextjs" by running Docusaurus locally and confirming the link renders under Guides > Integration Solutions.

content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx (1)

118-169: Custom styling section: clear and accurate.

Theme injection via CSS variables and the theme prop reads well. Importing the UI CSS is correctly shown here for generic React apps.

Comment thread content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx Outdated
Comment thread content/800-guides/360-embed-studio-nextjs.mdx
Comment thread content/800-guides/360-embed-studio-nextjs.mdx
Comment thread content/800-guides/360-embed-studio-nextjs.mdx
Comment thread content/800-guides/360-embed-studio-nextjs.mdx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx (3)

194-199: Import cors in Hono example.

cors() is used but not imported.

 import { Hono } from "hono";
+import { cors } from "hono/cors";
 import { createPrismaPostgresHttpClient } from "@prisma/studio-core/data/ppg";
 import { serializeError } from "@prisma/studio-core/data/bff";
 
 const app = new Hono().use("*", cors());

306-313: Use user’s database URL rather than API key in auth section.

This contradicts earlier guidance that the backend uses DATABASE_URL. Replace API key wording and adjust the example.

-// In your server-side implementation, you can then retrieve these values from the incoming request and extract the Prisma Postgres API key that's needed for this user's query:
+// In your server-side implementation, you can then retrieve these values from the incoming request
+// and determine the DATABASE_URL (connection string) for this user's query:

Follow-up code:

-const userApiKey = await getUserApiKey(userId, token);
+const url = await getUserDatabaseUrl(userId, token);
+// ...then pass `url` into `createPrismaPostgresHttpClient({ url })` in your handler

If you want to keep an API-key-based flow, add a parallel example that shows the appropriate client and env/config requirements, and clearly separate the two approaches.


31-33: Update Prisma Postgres provisioning instructions

The current bullet “you can create one with npx prisma init --db” is misleading—prisma init only scaffolds your project/schema. Provisioning a Postgres instance is a separate step. Please replace it with correct hosted vs. local workflows:

-  - A Prisma Postgres instance (you can create one with `npx prisma init --db`)
+  - A Prisma Postgres instance (hosted: provision via the Prisma Data Platform Console and copy the generated `DATABASE_URL` into your `.env`; local: run `npx prisma dev` to start a local Postgres instance and use the printed `DATABASE_URL`)

See the Prisma Postgres guides for details:

♻️ Duplicate comments (1)
content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx (1)

183-186: Replace API key wording with DATABASE_URL to match implementation.

The minimal backend implementation uses DATABASE_URL. The paragraph still references a “Prisma Postgres API key,” which conflicts with the rest of the doc.

-Your backend needs to expose a `/studio` endpoint where the frontend sends its requests. The implementation below uses `createPrismaPostgresHttpClient` from `@prisma/studio-core`. 
-
-The backend also needs to have access to the Prisma Postgres API key, we recommend setting it as an environment variable as a best practice.
+Your backend needs to expose a `/studio` endpoint where the frontend sends its requests. The implementation below uses `createPrismaPostgresHttpClient` from `@prisma/studio-core`.
+
+Ensure your backend can read the database connection string via an environment variable (for example, `DATABASE_URL`). Avoid embedding credentials in client code.
🧹 Nitpick comments (7)
content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx (7)

23-23: Grammar: “an quick” → “a quick”.

Small copy fix.

-- Create an quick admin dashboard for editing data
+- Create a quick admin dashboard for editing data

57-61: Import React/useMemo and terminate CSS import for correctness and consistency.

The example uses useMemo but doesn’t import it. Also add a semicolon to the CSS import for consistency with other examples.

+import React, { useMemo } from "react";
 import { Studio } from "@prisma/studio-core/ui";
 import { createPostgresAdapter } from "@prisma/studio-core/data/postgres-core";
 import { createStudioBFFClient } from "@prisma/studio-core/data/bff";
-import "@prisma/studio-core/ui/index.css"
+import "@prisma/studio-core/ui/index.css";

87-91: Repeat: import React/useMemo and terminate CSS import.

Same as the minimal example.

+import React, { useMemo } from "react";
 import { Studio } from "@prisma/studio-core/ui";
 import { createPostgresAdapter } from "@prisma/studio-core/data/postgres-core";
 import { createStudioBFFClient } from "@prisma/studio-core/data/bff";
-import "@prisma/studio-core/ui/index.css"
+import "@prisma/studio-core/ui/index.css";

118-169: Avoid Tailwind-specific @layer in injected theme string; switch to plain CSS variables.

The theme prop likely injects raw CSS at runtime. The @layer directive is a Tailwind/PostCSS construct and won’t be processed by the browser when injected as-is. Recommend using plain :root and .dark scopes.

-const customTheme = `
-@layer base {
-  :root {
-    --background: 0 0% 100%;
-    --foreground: 20 14.3% 4.1%;
-    --primary: 47.9 95.8% 53.1%;
-    --primary-foreground: 26 83.3% 14.1%;
-    --border: 20 5.9% 90%;
-    --input: 20 5.9% 90%;
-    --ring: 20 14.3% 4.1%;
-    --radius: 0rem;
-  }
-
-  .dark {
-    --background: 20 14.3% 4.1%;
-    --foreground: 60 9.1% 97.8%;
-    --primary: 47.9 95.8% 53.1%;
-    --primary-foreground: 26 83.3% 14.1%;
-    --border: 12 6.5% 15.1%;
-    --input: 12 6.5% 15.1%;
-    --ring: 35.5 91.7% 32.9%;
-  }
-}
-`;
+const customTheme = `
+:root {
+  --background: 0 0% 100%;
+  --foreground: 20 14.3% 4.1%;
+  --primary: 47.9 95.8% 53.1%;
+  --primary-foreground: 26 83.3% 14.1%;
+  --border: 20 5.9% 90%;
+  --input: 20 5.9% 90%;
+  --ring: 20 14.3% 4.1%;
+  --radius: 0rem;
+}
+
+.dark {
+  --background: 20 14.3% 4.1%;
+  --foreground: 60 9.1% 97.8%;
+  --primary: 47.9 95.8% 53.1%;
+  --primary-foreground: 26 83.3% 14.1%;
+  --border: 12 6.5% 15.1%;
+  --input: 12 6.5% 15.1%;
+  --ring: 35.5 91.7% 32.9%;
+}
+`;

If the theme prop supports CSS files or Tailwind processing, consider clarifying that. Otherwise, this change ensures the theme works without a build step.


205-209: Handle missing DATABASE_URL for robustness of example.

Add a simple guard and return an error if the env var is not set.

   // 2. Read DB URL from env vars
   const url = process.env.DATABASE_URL;
+  if (!url) {
+    return c.json([serializeError(new Error("DATABASE_URL is not set"))], 500);
+  }
   
   // 3. Execute the query against Prisma Postgres
   const [error, results] = await createPrismaPostgresHttpClient({ url }).execute(query);

245-247: Align comment with code: mention Prisma Postgres only (or add Accelerate example).

The code uses createPrismaPostgresHttpClient. Either remove “or Prisma Accelerate” here or add a parallel snippet for Accelerate.

-  // 5. Execute the query using Prisma Postgres or Prisma Accelerate
+  // 5. Execute the query using Prisma Postgres

270-288: Update commented mermaid diagram: avoid API key phrasing.

Even though this is commented out, it can confuse future edits. Prefer “determine/read DATABASE_URL.”

-    Backend->>Backend: Extract API key from request
+    Backend->>Backend: Determine DATABASE_URL from context/env
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between db9e3cf and cafe47e.

📒 Files selected for processing (1)
  • content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Check internal links
  • GitHub Check: runner / linkspector
  • GitHub Check: Lost Pixel
🔇 Additional comments (2)
content/250-postgres/300-database/675-prisma-studio/100-embedding-studio.mdx (2)

13-13: Good clarification on executor and DATABASE_URL usage.

Clear, accurate description of the executor and backend connection via DATABASE_URL. This resolves earlier confusion around API key usage.


294-304: Passing auth headers from the frontend looks good.

Clear example of forwarding user context via headers to the BFF.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 19, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (5)
content/800-guides/360-embed-studio-nextjs.mdx (5)

385-390: Suspense fallback won’t show without dynamic({ suspense: true }) or a loading option.

As written, <Suspense> fallback won’t render for this dynamic import. Choose one fix and apply consistently.

Option A — keep <Suspense>:

 const Studio = dynamic(
   () => import("@prisma/studio-core/ui").then(mod => mod.Studio),
   {
-    ssr: false
+    ssr: false,
+    suspense: true
   }
 );
 ...
   <StudioWrapper>
-    <Suspense fallback={<StudioLoading />}>
-      <ClientOnlyStudio />
-    </Suspense>
+    <Suspense fallback={<StudioLoading />}>
+      <ClientOnlyStudio />
+    </Suspense>
   </StudioWrapper>

Option B — remove <Suspense> and use loading:

 const Studio = dynamic(
   () => import("@prisma/studio-core/ui").then(mod => mod.Studio),
   {
-    ssr: false
+    ssr: false,
+    loading: () => <StudioLoading />
   }
 );
 ...
   <StudioWrapper>
-    <Suspense fallback={<StudioLoading />}>
-      <ClientOnlyStudio />
-    </Suspense>
+    <ClientOnlyStudio />
   </StudioWrapper>

Also applies to: 419-423


91-93: Remove unsupported prisma init flag and fix the command.

prisma init doesn’t support --output. Running the current command will fail. Use the plain init with --db.

-npx prisma init --db --output ../app/generated/prisma
+npx prisma init --db

100-106: Correct what prisma init creates (client output dir isn’t created at init).

The client output directory is created when you run prisma migrate dev (or prisma generate), not by prisma init.

 The `prisma init --db` command creates:
 - A `prisma/` directory with your `schema.prisma` file
 - A new Prisma Postgres database
 - A `.env` file with your `DATABASE_URL`
-- An output directory at `app/generated/prisma` for the Prisma Client
+- The Prisma Client will be generated (and its output directory created) when you run:
+  - `npx prisma migrate dev` (recommended), or
+  - `npx prisma generate`

259-260: Clarify backend connection: use DATABASE_URL, not “API key”.

The route uses process.env.DATABASE_URL. Replace “API key” wording to avoid confusion.

-The `@prisma/studio-core` provides `Studio`, a React component which renders Prisma Studio for your database. The `Studio` component accepts an _executor_ which accesses a custom endpoint in your backend. The backend uses your API key to identify the correct Prisma Postgres instance and sends the SQL query to it.
+The @prisma/studio-core package provides `Studio`, a React component that renders Prisma Studio for your database. The `Studio` component accepts an executor that targets a backend endpoint. The backend reads your `DATABASE_URL` (connection string) to connect to Prisma Postgres and executes the SQL query.

265-297: Move global CSS import to app/layout.tsx (App Router rule).

Global CSS must be imported in the root layout, not inside components. Importing @prisma/studio-core/ui/index.css here will error in Next App Router.

 'use client';
-import "@prisma/studio-core/ui/index.css";
 import { ReactNode } from 'react';

Add this to your root layout:

// app/layout.tsx
import '@prisma/studio-core/ui/index.css';
import './globals.css';
import type { ReactNode } from 'react';

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}
🧹 Nitpick comments (5)
content/800-guides/360-embed-studio-nextjs.mdx (5)

81-84: Remove unused dependency.

@prisma/extension-accelerate isn’t used in this guide. Consider dropping it to keep the setup lean.

-npm install @prisma/extension-accelerate @prisma/client
+npm install @prisma/client

309-314: CORS: tighten in production.

Open CORS is fine for local dev. In production, restrict Access-Control-Allow-Origin to your domain.

-  "Access-Control-Allow-Origin": "*", // Change to your domain in production
+  "Access-Control-Allow-Origin": "*", // TODO: set to your domain in production, e.g. "https://yourapp.com"

317-323: Consider setting runtime explicitly to Node.js.

If you deploy to environments where Edge can be the default, process.env.DATABASE_URL may not be available. Explicitly opt into Node runtime to be safe.

 export const dynamic = "force-dynamic";
+export const runtime = "nodejs";

248-257: Tone down “--force” install guidance.

Suggest trying a clean install or resolving peer deps before --force to avoid opaque dependency trees.

Example alternatives:

  • Delete lockfile and node_modules, then reinstall.
  • Use --legacy-peer-deps with npm if peer conflicts arise.

29-37: Minor copy edits for clarity.

Tighten phrasing and remove redundancy.

-[**Embeddable Prisma Studio**](/postgres/database/prisma-studio/embedding-studio) is *free* and licensed under Apache 2.0.
+[**Embeddable Prisma Studio**](/postgres/database/prisma-studio/embedding-studio) is free and licensed under Apache 2.0.
 
 ✔️ Free to use in production
 ⚠️ Prisma branding must remain visible and unchanged
 🔐 To remove branding or learn about upcoming partner-only features, reach out at [partnerships@prisma.io](mailto:partnerships@prisma.io)
 
-Currently, Embedded Prisma Studio supports [**Prisma Postgres**](/postgres), with additional databases coming soon.
+Currently, embedded Prisma Studio supports [Prisma Postgres](/postgres). Additional databases are coming soon.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cafe47e and 88b471c.

📒 Files selected for processing (1)
  • content/800-guides/360-embed-studio-nextjs.mdx (1 hunks)
🧰 Additional context used
🪛 LanguageTool
content/800-guides/360-embed-studio-nextjs.mdx

[grammar] ~23-~23: There might be a mistake here.
Context: ...a quick admin dashboard for editing data - Supporting multi-tenant applications whe...

(QB_NEW_EN)


[grammar] ~24-~24: There might be a mistake here.
Context: ...s where each user has their own database - Giving users an easy way to view and edi...

(QB_NEW_EN)


[grammar] ~31-~31: There might be a mistake here.
Context: ...pache 2.0. ✔️ Free to use in production ⚠️ Prisma branding must remain visible a...

(QB_NEW_EN)


[grammar] ~33-~33: There might be a mistake here.
Context: ...es, reach out at partnerships@prisma.io Currently, Embedded Prisma Studio support...

(QB_NEW_EN)


[grammar] ~41-~41: There might be a mistake here.
Context: .... ::: ## Prerequisites - Node.js 18+ - Basic knowledge of React and Next.js - A...

(QB_NEW_EN)


[grammar] ~42-~42: There might be a mistake here.
Context: ...) - Basic knowledge of React and Next.js - A Prisma Postgres database ## 1. Setti...

(QB_NEW_EN)


[style] ~53-~53: Consider removing “of” to be more concise
Context: ...ew questions about your project. Select all of the defaults. :::info For reference, thos...

(ALL_OF_THE)


[grammar] ~59-~59: There might be a mistake here.
Context: ... For reference, those are: - TypeScript - ESLint - Tailwind CSS - No src directo...

(QB_NEW_EN)


[grammar] ~60-~60: There might be a mistake here.
Context: ...rence, those are: - TypeScript - ESLint - Tailwind CSS - No src directory - App ...

(QB_NEW_EN)


[grammar] ~61-~61: There might be a mistake here.
Context: ...e: - TypeScript - ESLint - Tailwind CSS - No src directory - App Router - Turbop...

(QB_NEW_EN)


[grammar] ~62-~62: There might be a mistake here.
Context: ...Lint - Tailwind CSS - No src directory - App Router - Turbopack - Select default ...

(QB_NEW_EN)


[grammar] ~63-~63: There might be a mistake here.
Context: ...nd CSS - No src directory - App Router - Turbopack - Select default import alias ...

(QB_NEW_EN)


[grammar] ~64-~64: There might be a mistake here.
Context: ...src directory - App Router - Turbopack - Select default import alias ::: Then, ...

(QB_NEW_EN)


[grammar] ~102-~102: There might be a mistake here.
Context: ...directory with your schema.prisma file - A new Prisma Postgres database - A `.env...

(QB_NEW_EN)


[grammar] ~103-~103: There might be a mistake here.
Context: ...afile - A new Prisma Postgres database - A.envfile with yourDATABASE_URL` -...

(QB_NEW_EN)


[grammar] ~104-~104: There might be a mistake here.
Context: ...gres database - A .env file with your DATABASE_URL - An output directory at `app/generated/pr...

(QB_NEW_EN)


[grammar] ~256-~256: There might be a mistake here.
Context: ..., use the equivalent flag for your tool. ::: The @prisma/studio-core provides ...

(QB_NEW_EN)


[style] ~303-~303: Consider a more expressive alternative.
Context: ...s (or errors) back to the frontend. To do this, create a new folder called api ...

(DO_ACHIEVE)


[grammar] ~444-~444: There might be a mistake here.
Context: ...uld appear. 3. Interactive features: - Browse and filter records in your tables...

(QB_NEW_EN)


[style] ~447-~447: ‘new records’ might be wordy. Consider a shorter alternative.
Context: ...nline by double-clicking cells - Add new records using the "Add record" button - Dele...

(EN_WORDINESS_PREMIUM_NEW_RECORDS)


[style] ~455-~455: ‘new record’ might be wordy. Consider a shorter alternative.
Context: ...o check that changes are saved. - Add a new record and confirm it appears instantly. - Try...

(EN_WORDINESS_PREMIUM_NEW_RECORD)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Check internal links
  • GitHub Check: runner / linkspector
  • GitHub Check: Lost Pixel
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
content/800-guides/360-embed-studio-nextjs.mdx (1)

346-357: Good error protocol: matches expected [error, result] tuple.

Returning [serializeError(error)] on failure and [null, results] on success aligns with Studio’s executor protocol.

Comment thread content/800-guides/360-embed-studio-nextjs.mdx
Comment thread content/800-guides/360-embed-studio-nextjs.mdx
mhessdev
mhessdev previously approved these changes Aug 19, 2025

@mhessdev mhessdev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ankur-arch could we embed ryans video? Or link to it? Would that be relevant?

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (6)
content/800-guides/360-embed-studio-nextjs.mdx (6)

112-116: Avoid custom Prisma Client output; use the default package.

Customizing generator client.output complicates imports across the app and the guide. Recommend removing it and using the standard @prisma/client.

 generator client {
   provider = "prisma-client-js"
-  output   = "../app/generated/prisma"
 }

159-162: Update seed import to use the default client package.

If you remove the custom output (recommended), import from @prisma/client.

-import { PrismaClient } from '../app/generated/prisma'
+import { PrismaClient } from '@prisma/client'

266-268: Global CSS must be imported in app/layout.tsx, not in a component (App Router rule).

Importing @prisma/studio-core/ui/index.css inside a component can break in the App Router. Move it to app/layout.tsx.

Apply:

 'use client';
-import "@prisma/studio-core/ui/index.css";
 import { ReactNode } from 'react';

Then ensure your root layout includes:

// app/layout.tsx
import '@prisma/studio-core/ui/index.css';
import './globals.css';
import type { ReactNode } from 'react';

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

385-390: Suspense fallback won’t render with dynamic() unless you enable suspense or use the loading option.

Your <Suspense> boundary won’t show its fallback because next/dynamic isn’t configured for Suspense. Choose one:

  • Option A (keep Suspense): enable suspense: true.
  • Option B (simpler): remove <Suspense> and provide a loading component via dynamic().

Option A:

 const Studio = dynamic(
   () => import("@prisma/studio-core/ui").then(mod => mod.Studio),
   {
-    ssr: false
+    ssr: false,
+    suspense: true
   }
 );

Option B:

 const Studio = dynamic(
   () => import("@prisma/studio-core/ui").then(mod => mod.Studio),
   {
-    ssr: false
+    ssr: false,
+    loading: () => <StudioLoading />
   }
 );
 ...
-      <Suspense fallback={<StudioLoading />}>
-        <ClientOnlyStudio />
-      </Suspense>
+      <ClientOnlyStudio />

Also applies to: 420-423


91-93: Remove unsupported --output flag from prisma init and fix the description of what it creates.

  • prisma init does not accept --output and does not generate the Prisma Client or its output directory.
  • Keep “init --db” and clarify that Client is generated by migrate dev/generate.

Apply:

-npx prisma init --db --output ../app/generated/prisma
+npx prisma init --db

And adjust the bullets below:

 The `prisma init --db` command creates:
 
 - A `prisma/` directory with your `schema.prisma` file
 - A new Prisma Postgres database
 - A `.env` file with your `DATABASE_URL`
-- An output directory at `app/generated/prisma` for the Prisma Client
+
+Note: Prisma Client will be generated (and its output directory created) when you run `npx prisma migrate dev` (or `npx prisma generate`).

Also applies to: 100-106


259-260: Clarify how the backend connects: it reads DATABASE_URL, not an API key.

The route uses process.env.DATABASE_URL. Replace “API key” wording to avoid confusion.

-The `@prisma/studio-core` provides `Studio`, a React component which renders Prisma Studio for your database. The `Studio` component accepts an _executor_ which accesses a custom endpoint in your backend. The backend uses your API key to identify the correct Prisma Postgres instance and sends the SQL query to it.
+The `@prisma/studio-core` provides `Studio`, a React component which renders Prisma Studio for your database. The `Studio` component accepts an executor that calls a custom endpoint in your backend. The backend reads your `DATABASE_URL` (connection string) to connect to Prisma Postgres and executes the SQL query.
🧹 Nitpick comments (1)
content/800-guides/360-embed-studio-nextjs.mdx (1)

81-84: Minimize dependencies: drop @prisma/extension-accelerate if unused.

The guide doesn’t use Accelerate in any snippet. Consider omitting it to keep setup lean.

-npm install @prisma/extension-accelerate @prisma/client
+npm install @prisma/client

If you intend to show Accelerate usage, add a short example or note why it’s installed.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 88b471c and 481de1b.

📒 Files selected for processing (1)
  • content/800-guides/360-embed-studio-nextjs.mdx (1 hunks)
🧰 Additional context used
🪛 LanguageTool
content/800-guides/360-embed-studio-nextjs.mdx

[grammar] ~23-~23: There might be a mistake here.
Context: ...a quick admin dashboard for editing data - Supporting multi-tenant applications whe...

(QB_NEW_EN)


[grammar] ~24-~24: There might be a mistake here.
Context: ...s where each user has their own database - Giving users an easy way to view and edi...

(QB_NEW_EN)


[grammar] ~31-~31: There might be a mistake here.
Context: ...pache 2.0. ✔️ Free to use in production ⚠️ Prisma branding must remain visible a...

(QB_NEW_EN)


[grammar] ~33-~33: There might be a mistake here.
Context: ...es, reach out at partnerships@prisma.io Currently, Embedded Prisma Studio support...

(QB_NEW_EN)


[grammar] ~41-~41: There might be a mistake here.
Context: .... ::: ## Prerequisites - Node.js 18+ - Basic knowledge of React and Next.js - A...

(QB_NEW_EN)


[grammar] ~42-~42: There might be a mistake here.
Context: ...) - Basic knowledge of React and Next.js - A Prisma Postgres database ## 1. Setti...

(QB_NEW_EN)


[style] ~53-~53: Consider removing “of” to be more concise
Context: ...ew questions about your project. Select all of the defaults. :::info For reference, thos...

(ALL_OF_THE)


[grammar] ~59-~59: There might be a mistake here.
Context: ... For reference, those are: - TypeScript - ESLint - Tailwind CSS - No src directo...

(QB_NEW_EN)


[grammar] ~60-~60: There might be a mistake here.
Context: ...rence, those are: - TypeScript - ESLint - Tailwind CSS - No src directory - App ...

(QB_NEW_EN)


[grammar] ~61-~61: There might be a mistake here.
Context: ...e: - TypeScript - ESLint - Tailwind CSS - No src directory - App Router - Turbop...

(QB_NEW_EN)


[grammar] ~62-~62: There might be a mistake here.
Context: ...Lint - Tailwind CSS - No src directory - App Router - Turbopack - Select default ...

(QB_NEW_EN)


[grammar] ~63-~63: There might be a mistake here.
Context: ...nd CSS - No src directory - App Router - Turbopack - Select default import alias ...

(QB_NEW_EN)


[grammar] ~64-~64: There might be a mistake here.
Context: ...src directory - App Router - Turbopack - Select default import alias ::: Then, ...

(QB_NEW_EN)


[grammar] ~102-~102: There might be a mistake here.
Context: ...directory with your schema.prisma file - A new Prisma Postgres database - A `.env...

(QB_NEW_EN)


[grammar] ~103-~103: There might be a mistake here.
Context: ...afile - A new Prisma Postgres database - A.envfile with yourDATABASE_URL` -...

(QB_NEW_EN)


[grammar] ~104-~104: There might be a mistake here.
Context: ...gres database - A .env file with your DATABASE_URL - An output directory at `app/generated/pr...

(QB_NEW_EN)


[grammar] ~256-~256: There might be a mistake here.
Context: ..., use the equivalent flag for your tool. ::: The @prisma/studio-core provides ...

(QB_NEW_EN)


[style] ~303-~303: Consider a more expressive alternative.
Context: ...s (or errors) back to the frontend. To do this, create a new folder called api ...

(DO_ACHIEVE)


[grammar] ~444-~444: There might be a mistake here.
Context: ...uld appear. 3. Interactive features: - Browse and filter records in your tables...

(QB_NEW_EN)


[style] ~447-~447: ‘new records’ might be wordy. Consider a shorter alternative.
Context: ...nline by double-clicking cells - Add new records using the "Add record" button - Dele...

(EN_WORDINESS_PREMIUM_NEW_RECORDS)


[style] ~455-~455: ‘new record’ might be wordy. Consider a shorter alternative.
Context: ...o check that changes are saved. - Add a new record and confirm it appears instantly. - Try...

(EN_WORDINESS_PREMIUM_NEW_RECORD)


[grammar] ~474-~474: There might be a mistake here.
Context: ...://www.youtube.com/watch?v=Up5vG2YHPvc).

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Lost Pixel
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (2)
content/800-guides/360-embed-studio-nextjs.mdx (2)

315-369: Solid API bridge: good error serialization, CORS handling, and dynamic rendering.

  • force-dynamic avoids cache issues for DB ops.
  • Error path consistently serializes via serializeError.
  • CORS + OPTIONS handler are clear with prod note.

402-415: Frontend wiring looks correct.

createStudioBFFClientcreatePostgresAdapter<Studio adapter={...} /> is the intended flow for embedding Studio through your /api/studio bridge.

@ankur-arch
ankur-arch merged commit 94891bc into main Aug 21, 2025
9 of 10 checks passed
@ankur-arch
ankur-arch deleted the DC-4813 branch August 21, 2025 11:30
jlecordier pushed a commit to jlecordier/docs-1 that referenced this pull request Sep 3, 2025
* fix: add guide intro

* feat: refine guide

* enhance: add finishing touches to guide

* Optimised images with calibre/image-actions

* fix: add coderabbit nits

* fix: add note for peer deps issue

* fix: add a callout to the YT video

* fix: update video link

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants