From 0f6e49de169b4ce5d836dda0746c5bee2b553e42 Mon Sep 17 00:00:00 2001 From: Gregory Boch Date: Wed, 30 Sep 2026 12:04:09 +0200 Subject: [PATCH 1/9] site: /compute claims pass with the entity line, an FAQ and compare links See the pull request description for the change list and the facts checked. Co-Authored-By: Claude Fable 5.1 --- apps/site/src/app/compute/page.tsx | 15 +- .../src/components/product/content/compute.ts | 142 +++++++++++++----- .../product/illustrations/agent-hosting.tsx | 13 +- .../product/illustrations/branched-stack.tsx | 12 +- .../product/illustrations/co-located.tsx | 28 ++-- .../product/illustrations/deploy-log.tsx | 24 +-- .../product/illustrations/deployments.tsx | 17 ++- .../illustrations/isolated-branches.tsx | 5 +- .../product/illustrations/repo-connect.tsx | 14 +- .../product/illustrations/run-apps.tsx | 19 ++- apps/site/src/components/product/types.ts | 3 +- apps/site/src/lib/markdown-pages.ts | 6 +- .../src/lib/markdown/markdown-parity.test.ts | 1 + 13 files changed, 200 insertions(+), 99 deletions(-) diff --git a/apps/site/src/app/compute/page.tsx b/apps/site/src/app/compute/page.tsx index 0f0cfc0c14d..1cfe5319ca1 100644 --- a/apps/site/src/app/compute/page.tsx +++ b/apps/site/src/app/compute/page.tsx @@ -5,19 +5,26 @@ import { ProductFeatures } from "@/components/product/product-features"; import { ProductHero } from "@/components/product/product-hero"; import { ProductPlatform } from "@/components/product/product-platform"; import { ProductProblem } from "@/components/product/product-problem"; +import { CompareLinks } from "@/components/sections/compare-links"; +import { Faq } from "@/components/sections/faq"; export const metadata = createPageMetadata({ title: "Prisma Compute | Deploy TypeScript Apps and AI Agents on Bun", + // The entity wording shared with the homepage, /postgres and the docs, kept + // verbatim. lib/markdown-pages.ts repeats it for the .md rendition. description: - "Prisma Compute deploys TypeScript apps, APIs, and AI agents from your repo as long-lived Bun processes next to Prisma Postgres, with long-running requests and streaming. One platform for your app and its database.", + "Prisma Compute hosts TypeScript apps (Node.js, Bun or Next.js) next to Prisma Postgres on one plan. Generally available since August 2026. Free plan, no credit card. Any Postgres client works; Prisma ORM is optional.", path: "/compute", ogKicker: "Prisma Compute", ogAccent: "red", }); // /compute composes the product sections directly, like /orm: V4 gives this page -// no testimonial section, so it can't go through ProductPage. It adds no extra -// sections either, so this is the template's plain shape minus the testimonials. +// no testimonial section, so it can't go through ProductPage. Apart from that +// it is the template's shape, including the two optional sections ProductPage +// renders for /postgres: the shared "Compare Prisma" list and a visible FAQ, +// both read from computeContent so lib/markdown/product.ts prints them in the +// same order. export default function ComputePage() { return ( <> @@ -29,6 +36,8 @@ export default function ComputePage() { + {computeContent.compare ? : null} + {computeContent.faq ? : null} ); diff --git a/apps/site/src/components/product/content/compute.ts b/apps/site/src/components/product/content/compute.ts index 4bc475fe736..17d00826c33 100644 --- a/apps/site/src/components/product/content/compute.ts +++ b/apps/site/src/components/product/content/compute.ts @@ -1,7 +1,9 @@ +import { siteConfig } from "@/lib/config"; import type { ProductPageContent } from "../types"; // /compute copy, from the approved V4 of the Notion card "Product Page Batch -// One (3-5) - Copy", with the 2026-08-06 client review's changes marked inline. +// One (3-5) - Copy", with the 2026-08-06 client review's changes marked inline +// and the 2026-09-30 claims pass applied on top (see the second note). // // The review asked this page for three things, and the hero tour answers all // three: show the deployment experience immediately (Connect → Deploy → Live), @@ -11,56 +13,85 @@ import type { ProductPageContent } from "../types"; // Three things V4 deliberately does on this page: // - No testimonial section. /orm and /postgres carry one; Compute does not, // which is why this page composes its sections directly. -// - No "in public beta" callout. V3 had one and V4 removed it — don't -// reintroduce it from the homepage, which still labels Compute as beta. -// - Five features (V4 shipped four; Object Store buckets, launched 2026-07-24, -// were added after the review), rendered three-then-two with the last pair -// centred — see product-features.tsx. +// - No "in public beta" callout. V3 had one and V4 removed it. Compute has +// been generally available since August 2026, and the microline says so. +// - Four features, rendered two by two (see product-features.tsx). V4 shipped +// four; Object Store buckets, launched 2026-07-24, were added after the +// review, and the cron card left in the claims pass. +// +// Claims pass, 2026-09-30: every product sentence on this page now has a line +// in apps/docs behind it. What went, and why: +// - "the easiest way to host", "microsecond", "same machine", "no code +// changes": superlatives and latency figures nothing in the docs states. +// - "every PR", "branched from production", "branched together": previews are +// per pushed branch and need deploy on push set up first +// (compute/deploy-on-push.mdx), and production data is not copied into them +// (compute/limitations.mdx, "Databases and migrations"). +// - "deploy it as it is", "long-running", "durable memory": an existing app +// adds a Composer declaration first (composer/porting-an-app.mdx), and the +// keep-awake primitives are best-effort, not durable +// (compute/keeping-instances-awake.mdx). +// - "low-latency queries" and "skip the cross-vendor network hop": the softer +// cousins of the latency claim. The docs say only that the app runs next +// to Prisma Postgres (compute/index.mdx), so the page says that. +// - The cron card: cron scheduling is not part of this release and there is +// no committed Compute config file (compute/limitations.mdx, "Runtime" and +// "CLI"). It returns only as a Composer scheduled-jobs card once the +// product team confirms one; the configJobs illustration stays for that. const CONSOLE = "https://console.prisma.io/sign-up"; const DOCS = "/docs"; +// The trust line the brief puts on the homepage, /compute and /postgres. Its +// numbers are siteConfig.proof's first and last entries (developers, GitHub +// stars), the same source as the homepage hero, so the pages cannot drift +// apart. The market-share entry between them stays off this page. +const developers = siteConfig.proof[0]; +const stars = siteConfig.proof[2]; +const TRUST_LINE = `Trusted by ${developers.stat} ${developers.label} · ${stars.stat} ${stars.label}`; + export const computeContent: ProductPageContent = { name: "Prisma Compute", accent: "compute", hero: { headline: "One platform for your app and its database", headlineEmphasis: "One platform", - // V4's second sentence is dropped from the hero — it pushed the CTA down, - // and the tour beside this copy now demonstrates both halves of it. + // The first sentence of the entity wording shared with the homepage, + // /postgres and the docs. The microline carries its second and third + // sentences; the page's meta description (app/compute/page.tsx) carries + // all four verbatim. subheadline: - "Prisma Compute is the easiest way to host TypeScript apps, with Postgres and the rest of your infrastructure built in.", + "Prisma Compute hosts TypeScript apps (Node.js, Bun or Next.js) next to Prisma Postgres on one plan.", benefits: [ - "Every PR gets a dedicated app and database, branched together", - "Microsecond app-to-database latency, no cross-vendor network hop", - "Long-running, streaming workloads built for hosting agents, not just apps", + "Set up deploy on push, and every pushed branch gets a preview with its own database", + "Your app runs next to Prisma Postgres, in one of six regions", + "Streams responses and scales to zero when idle, for agents as well as apps", ], primaryCta: { label: "Get started free", href: CONSOLE }, secondaryCta: { label: "Read the docs", href: DOCS }, - // Deliberately not "free while in public beta" — see the note at the top - // of this file. This says the same encouraging thing without the label. - microline: "Deploy from GitHub or the CLI. Free tier, no credit card.", + microline: "Generally available since August 2026. Free plan, no credit card.", tour: [ { label: "Connect", caption: - "Point Compute at a GitHub repo, or deploy straight from your machine with one command.", + "Deploy from your machine with npx prisma deploy module.ts, or connect the GitHub repo and add the deploy workflow to deploy on every push.", illustration: "repoConnect", }, { label: "Deploy", caption: - "One deploy ships the app and its branched database together, migrations included.", + "One deploy provisions the services and databases declared in module.ts, and applies the migrations of any database typed by a Prisma ORM contract.", illustration: "deployLog", }, { label: "Live", caption: - "Production and a per-PR preview, each with its own app and its own isolated database.", + "Production, plus a preview per pushed branch with its own services and database once deploy on push is set up.", illustration: "deployments", }, { label: "Apps", - caption: "Start from an app — Next.js, Hono, an API, an agent — and deploy it as it is.", + caption: + "Bring a Next.js, Hono or Bun app, or an agent: add a Composer declaration (service.ts and module.ts) around the server code you already have, then deploy.", illustration: "runApps", }, ], @@ -68,14 +99,14 @@ export const computeContent: ProductPageContent = { problem: { headline: "One platform can ship features two never could", body: [ - "When your hosting provider and your database provider are separate companies, the things that depend on them being aware of each other (branching, preview environments, low-latency queries, end-to-end test data) don't exist. You wire them together yourself, or you do without.", + "When your hosting provider and your database provider are separate companies, the things that depend on them being aware of each other (branching, preview environments, end-to-end test data) don't exist. You wire them together yourself, or you do without.", "Prisma Compute exists to change that.", ], outcomes: [ - { icon: "gitBranch", label: "Branch your stack per PR" }, - { icon: "rocket", label: "Skip the cross-vendor network hop" }, + { icon: "gitBranch", label: "A preview per pushed branch" }, + { icon: "rocket", label: "Ship app and database in one deploy" }, { icon: "bot", label: "Host streaming agents natively" }, - { icon: "settings", label: "One config for app and database" }, + { icon: "settings", label: "One module.ts for app and database" }, ], }, features: { @@ -89,27 +120,21 @@ export const computeContent: ProductPageContent = { { name: "Built for hosting AI agents", description: - "Agents need long-lived processes, streaming responses and durable memory. Compute supports all three, on the same platform that runs your data.", + "Agents stream their answers and spend most of their time waiting on a model API. Compute streams a response as your service sends it, bills memory and active CPU separately, and scales to zero between tasks.", illustration: "agentHosting", }, { - name: "Branch your stack per PR", + name: "A preview per pushed branch", description: - "Every preview environment gets a dedicated database, branched from production and tied to that deploy. No shared test DB that passes tests production fails.", + "Once deploy on push is set up, every pushed branch gets its own services and its own database, built from your migrations, and deleting the branch tears them down. No shared test DB that passes tests production fails.", illustration: "branchedStack", }, { - name: "Microsecond queries, no code changes", + name: "App and database on one platform", description: - "ORMs make many small queries, and on most stacks each one pays a network round trip between two vendors. Compute runs on the same machine as Prisma Postgres, so that round trip disappears.", + "Your app runs next to Prisma Postgres, in the same project and on the same plan, with PgBouncer pooling included. Any Postgres client works, and Prisma ORM is optional.", illustration: "coLocated", }, - { - name: "Cron and background jobs as a first-class concept", - description: - "Scheduled execution and background jobs are declared in prisma.config.ts, alongside the rest of your app. No external schedulers, no separate sidecar service.", - illustration: "configJobs", - }, { name: "S3-compatible file storage built in", description: @@ -120,15 +145,56 @@ export const computeContent: ProductPageContent = { ], }, platform: { - body: "Prisma Compute is where the stack comes together: your app, your database, and your data model on one platform.", + // The second sentence is the exit line shared with /postgres, verbatim. + body: "Prisma Compute is where the stack comes together: your app, your database, and your data model on one platform. Standard Postgres underneath: leave with pg_dump; the Composer module is a TypeScript file in your repo, not a runtime.", + }, + // The shared "Compare Prisma" reading list (sections/compare-links.tsx), the + // same list /postgres and /pricing show. Only the sentence above it is this + // page's own, so it must not repeat theirs. + compare: { + intro: + "How Prisma Compute and Prisma Postgres compare with the other hosting and Postgres options, and where each one fits.", }, + // Visible text only: no FAQ schema, and every answer is a sentence the docs + // back (the PR's "facts checked" block names the line for each). Plain + // strings, the shape /postgres uses, so lib/markdown/product.ts prints them + // as they are; where an answer leans on a docs page it names the page in + // words. + faq: [ + { + question: "Can I host my existing GitHub repo with a TypeScript frontend and Node API here?", + answer: + "Yes, when the frontend and the API are TypeScript services built for Node.js, Bun or Next.js. Add a Composer declaration around the server code you already have (a service.ts per service and one module.ts); the porting guide in the docs has a prompt your coding agent can write it from. Deploy with npx prisma deploy module.ts. For deploy on push, connect the repository and add the prisma/cloud-deploy-action workflow; from then on every pushed branch gets a preview with its own database.", + }, + { + question: "What does Prisma Compute not do?", + answer: + "No WebSocket servers yet. Each service runs in one region, chosen from six. A request has 60 seconds to send its first byte, and a response that has started streaming is not cut off. No cron scheduling and no persistent filesystem. The runtime is Bun. The Compute FAQ in the docs has the full list of trade-offs.", + }, + { + question: "Do I need Prisma ORM?", + answer: + "No. Your app reaches Prisma Postgres, or any other Postgres, through a connection string, so any Postgres client works. Prisma ORM is optional.", + }, + { + question: "Is Prisma Compute related to Prisma Cloud?", + answer: + "No. Prisma Compute is unrelated to Palo Alto Networks' Prisma Cloud. Prisma makes Prisma ORM, Prisma Postgres and Prisma Compute, and the dashboard is Prisma Console.", + }, + { + question: "What does it cost?", + answer: + "The Free plan includes 1M requests, 360 GB-hours of memory, 4 active vCPU-hours and 10 GB of outbound bandwidth a month for Compute, and 200k operations, 500 MB and 50 databases for Prisma Postgres, with no credit card and no usage billing. Starter is $10 a month base plus metered compute: 5M requests and 1M operations are included, memory ($0.006 per GB-hour), active vCPU ($0.064 per hour) and bandwidth ($0.025 per GB) are metered from the first unit, and you can set a spend limit. An idle app scales to zero. The pricing page lists every plan.", + }, + ], cta: { headline: "One platform. Both layers. Features only possible because of it.", - body: "Compute is part of a TypeScript stack where hosting and the database travel as a unit. Branch them together, deploy them together, debug them together.", + body: "Compute is part of a TypeScript stack where hosting and the database travel as a unit: preview them together, deploy them together, debug them together.", benefits: [ "Built to host the agents you're building, not just the apps", - "Per-PR branching across app and database", - "Co-located queries with no cross-vendor latency", + "A preview per pushed branch, app and database together", + "App next to its database, on one plan", + TRUST_LINE, ], primaryCta: { label: "Get started free", href: CONSOLE }, secondaryCta: { label: "Read the docs", href: DOCS }, diff --git a/apps/site/src/components/product/illustrations/agent-hosting.tsx b/apps/site/src/components/product/illustrations/agent-hosting.tsx index eff127f745d..db8d9095e87 100644 --- a/apps/site/src/components/product/illustrations/agent-hosting.tsx +++ b/apps/site/src/components/product/illustrations/agent-hosting.tsx @@ -1,19 +1,22 @@ import { Bot, Database, Repeat } from "@/components/icons/forma"; import { Bar, CardChrome, SurfaceCard } from "./parts"; -// "Built for hosting AI agents" — the three things the copy says agents need, -// running in one place: a long-lived process, a streaming response, and durable -// memory. The streaming line ends in a caret so it reads as still arriving. +// "Built for hosting AI agents": the three things the copy says about hosting +// an agent here. The response streams, memory is held (and billed) while the +// agent waits on a model API, and the service scales to zero between tasks. +// The streaming line ends in a caret so it reads as still arriving. Nothing +// here says "durable": the keep-awake primitives are best-effort +// (compute/keeping-instances-awake.mdx). const NEEDS = [ - { icon: Repeat, label: "long-lived" }, { icon: Bot, label: "streaming" }, { icon: Database, label: "memory" }, + { icon: Repeat, label: "scale to zero" }, ]; export function AgentHosting() { return ( - +
diff --git a/apps/site/src/components/product/illustrations/branched-stack.tsx b/apps/site/src/components/product/illustrations/branched-stack.tsx index 761eb72b673..47259bd89f4 100644 --- a/apps/site/src/components/product/illustrations/branched-stack.tsx +++ b/apps/site/src/components/product/illustrations/branched-stack.tsx @@ -2,9 +2,11 @@ import { AppWindow, Database, GitBranch } from "@/components/icons/forma"; import { cn } from "@/lib/utils"; import { Bar, CardChrome, SurfaceCard } from "./parts"; -// "Branch your stack per PR" — production above, a PR branch below, and both -// halves of the stack peeling off together. The pairing is the point, so app and -// database always appear as one row, never as two independent things. +// "A preview per pushed branch": production above, a pushed branch's preview +// below, and both halves of the stack appearing together. The pairing is the +// point, so app and database always appear as one row, never as two +// independent things. Nothing here says the preview's data comes from +// production, because it does not. function StackRow({ label, accent }: { label: string; accent?: boolean }) { const chip = cn( @@ -32,7 +34,7 @@ function StackRow({ label, accent }: { label: string; accent?: boolean }) { export function BranchedStack() { return ( - +
@@ -52,7 +54,7 @@ export function BranchedStack() {

- branched from production + its own app and database

diff --git a/apps/site/src/components/product/illustrations/co-located.tsx b/apps/site/src/components/product/illustrations/co-located.tsx index 6dba5a728eb..d5e8483c482 100644 --- a/apps/site/src/components/product/illustrations/co-located.tsx +++ b/apps/site/src/components/product/illustrations/co-located.tsx @@ -1,17 +1,17 @@ -import { AppWindow, Database, XCircle } from "@/components/icons/forma"; +import { AppWindow, CheckBold, Database, XCircle } from "@/components/icons/forma"; import { CardChrome, SectionLabel, SurfaceCard } from "./parts"; -// "Microsecond queries, no code changes" — the round trip that disappears. Two -// vendors above with the network hop struck out, one machine below with the app -// and the database sitting next to each other. The only unit shown is µs, which -// the copy itself claims; no numbers are invented. +// "App and database on one platform": two vendors above, with the hop between +// them struck out, and one platform below with the app and the database side +// by side. No unit and no figure is shown. The docs state no latency number, +// so the illustration claims none. export function CoLocated() { return ( - +
- {/* two vendors: the hop you pay for */} + {/* two vendors: two dashboards, two bills, a network hop between them */}
Two vendors
@@ -21,26 +21,30 @@ export function CoLocated() { db
-

network round trip

+

+ two dashboards, two bills +

- {/* one machine: no hop at all */} + {/* one platform: the same project and plan */}
- One machine + One platform
app - µs + db
-

no code changes

+

+ one project, one plan +

diff --git a/apps/site/src/components/product/illustrations/deploy-log.tsx b/apps/site/src/components/product/illustrations/deploy-log.tsx index 5ff3abaac77..bec0a8af873 100644 --- a/apps/site/src/components/product/illustrations/deploy-log.tsx +++ b/apps/site/src/components/product/illustrations/deploy-log.tsx @@ -1,16 +1,20 @@ import { AppWindow, CheckBold, Database } from "@/components/icons/forma"; import { CardChrome, HeroPanel, StatRow } from "./parts"; -// Stop two of the /compute hero tour — "Deploy". The deploy itself, running: -// services detected, everything built, the database branched and migrated -// alongside the app, then a live URL. Real: the command, the step names, the -// service names and the hostname shape. The timings are this build's own — they -// are not a platform performance claim, and nothing here is a latency figure. +// Stop two of the /compute hero tour, "Deploy". The deploy itself, running: +// the services module.ts declares, uploaded from your build output, the +// database provisioned and migrated alongside the app, then a live URL. Real: +// the command shape and the hostname shape. The step names paraphrase what +// deploy does: it assembles what your build produced and does not build for +// you (cli/deploy.mdx, composer/deploying.mdx), so no step here says "built". +// The migrations step is what composer/databases.mdx describes for a database +// typed by a Prisma ORM contract. The timings are this build's own: they are +// not a platform performance claim, and nothing here is a latency figure. const STEPS = [ - { label: "detected 3 services", detail: "web · api · worker", time: "0.4s" }, - { label: "built services", detail: "3 of 3", time: "18.2s" }, - { label: "provisioned branched database", detail: "from main", time: "2.1s" }, + { label: "read module.ts", detail: "web · api · worker", time: "0.4s" }, + { label: "uploaded services", detail: "3 of 3", time: "18.2s" }, + { label: "provisioned database", detail: "postgres", time: "2.1s" }, { label: "ran migrations", detail: "3 applied", time: "1.3s" }, { label: "health check", detail: "200 OK", time: "0.9s" }, ]; @@ -26,7 +30,7 @@ function Chip({ icon: Icon, label }: { icon: typeof AppWindow; label: string }) export function DeployLog() { return ( - +

$ - prisma deploy + prisma deploy module.ts

{STEPS.map(({ label, detail, time }) => ( diff --git a/apps/site/src/components/product/illustrations/deployments.tsx b/apps/site/src/components/product/illustrations/deployments.tsx index ee50ac1c00a..a14dbd20e94 100644 --- a/apps/site/src/components/product/illustrations/deployments.tsx +++ b/apps/site/src/components/product/illustrations/deployments.tsx @@ -4,10 +4,11 @@ import { cn } from "@/lib/utils"; import { Bar, CardChrome, HeroPanel, SectionLabel } from "./parts"; // The /compute hero abstraction: the platform's core claim in one frame — a -// production deploy and a per-PR preview, each carrying an app and a database -// that were branched together. Real: the environment names, the preview -// hostname shape, and the deploy command. Abstracted: every commit subject and -// measured value. +// production deploy and a preview for a pushed branch, each carrying an app +// and its own database. Real: the environment names, the preview hostname +// shape, and the deploy command. Abstracted: every commit subject and measured +// value. The preview's database is its own, not a copy of production's, so the +// frame says "preview branch" rather than anything about branching data. function Pair({ accent }: { accent?: boolean }) { return ( @@ -40,7 +41,7 @@ function Pair({ accent }: { accent?: boolean }) { export function Deployments() { return ( - +
- {/* the preview that branches both halves together */} + {/* the preview, carrying both halves */}
Preview
@@ -75,7 +76,7 @@ export function Deployments() { pr-214 - branched together + preview branch @@ -107,7 +108,7 @@ export function Deployments() {

$ - prisma deploy + prisma deploy module.ts

diff --git a/apps/site/src/components/product/illustrations/isolated-branches.tsx b/apps/site/src/components/product/illustrations/isolated-branches.tsx index f7b17572e78..c2bae68b93b 100644 --- a/apps/site/src/components/product/illustrations/isolated-branches.tsx +++ b/apps/site/src/components/product/illustrations/isolated-branches.tsx @@ -9,7 +9,7 @@ const PREVIEWS = ["pr-214", "pr-207"]; export function IsolatedBranches() { return ( - +
{/* what it replaces */} @@ -18,7 +18,8 @@ export function IsolatedBranches() { shared test db
- {/* one isolated database per preview, branched from production */} + {/* one isolated database per preview, beside production; its data is + the preview's own, not a copy of production's */}
production diff --git a/apps/site/src/components/product/illustrations/repo-connect.tsx b/apps/site/src/components/product/illustrations/repo-connect.tsx index b9cefae4d48..41caf0fe2ac 100644 --- a/apps/site/src/components/product/illustrations/repo-connect.tsx +++ b/apps/site/src/components/product/illustrations/repo-connect.tsx @@ -2,14 +2,18 @@ import { ChevronsUpDown, Console, Copy, GitBranch, Github } from "@/components/i import { CardChrome, HeroPanel, StatRow } from "./parts"; // Stop one of the /compute hero tour — "Connect". The console's get-started -// screen as an abstraction: point Compute at a repo, or run one command from -// your machine. Real: the CLI line, the GitHub App install step, the repo and -// branch shape. Abstracted: the project id and the account picker. The repo -// path is deliberately the loud one — that is the recommended route in product. +// screen as an abstraction: connect the repo for deploy on push (the Console +// opens the pull request that adds the deploy workflow), or run one command +// from your machine. Real: the CLI line, the GitHub App install step, the repo +// and branch shape, the service names a module.ts declares. Abstracted: the +// project id and the account picker. The repo path is deliberately the loud +// one, since that is the recommended route in product. Connecting alone deploys +// nothing (compute/deploy-on-push.mdx), which is why the caption beside this +// panel names the workflow too. export function RepoConnect() { return ( - + + 5 starters} diff --git a/apps/site/src/components/product/types.ts b/apps/site/src/components/product/types.ts index 8048d70cc35..6278ba3aef5 100644 --- a/apps/site/src/components/product/types.ts +++ b/apps/site/src/components/product/types.ts @@ -108,7 +108,8 @@ export type ProductPageContent = { * The shared "Compare Prisma" reading list (sections/compare-links.tsx), * rendered after the platform section, with this page's own one-sentence * intro above it: the list repeats across pages, the sentence does not. - * Added 2026-09-30 for /postgres; /compute follows once its copy is approved. + * Added 2026-09-30 for /postgres. /compute carries it too and renders it + * from app/compute/page.tsx, since that page does not go through ProductPage. */ compare?: { intro: string }; /** diff --git a/apps/site/src/lib/markdown-pages.ts b/apps/site/src/lib/markdown-pages.ts index 6cfc97f794c..f25d0a73c08 100644 --- a/apps/site/src/lib/markdown-pages.ts +++ b/apps/site/src/lib/markdown-pages.ts @@ -95,11 +95,13 @@ export const markdownPages: Record = { "/compute": { path: "/compute", title: "Prisma Compute | Deploy TypeScript Apps and AI Agents on Bun", + // The entity wording, verbatim from app/compute/page.tsx. description: - "Prisma Compute deploys TypeScript apps, APIs, and AI agents from your repo as long-lived Bun processes next to Prisma Postgres, with long-running requests and streaming. One platform for your app and its database.", + "Prisma Compute hosts TypeScript apps (Node.js, Bun or Next.js) next to Prisma Postgres on one plan. Generally available since August 2026. Free plan, no credit card. Any Postgres client works; Prisma ORM is optional.", h1: productH1(computeContent), subheadline: productSubheadline(computeContent), - // /compute is the template minus the testimonials section. + // /compute is the template minus the testimonials section, plus the + // comparison links and FAQ its content object carries. renderBody: () => renderProductMarkdown({ content: computeContent, testimonials: false }), }, "/pricing": { diff --git a/apps/site/src/lib/markdown/markdown-parity.test.ts b/apps/site/src/lib/markdown/markdown-parity.test.ts index 7226112ee6a..8710f6031c9 100644 --- a/apps/site/src/lib/markdown/markdown-parity.test.ts +++ b/apps/site/src/lib/markdown/markdown-parity.test.ts @@ -53,6 +53,7 @@ const PAGE_SOURCES: Record = { "src/components/product/product-problem.tsx", "src/components/product/product-features.tsx", "src/components/product/product-platform.tsx", + "src/components/sections/compare-links.tsx", ], "/pricing": [ "src/app/pricing/page.tsx", From 27abe0c51f021a043d3d84518576c35267ce3ea6 Mon Sep 17 00:00:00 2001 From: Gregory Boch Date: Wed, 30 Sep 2026 14:01:01 +0200 Subject: [PATCH 2/9] site: say which preview databases get migrations applied on deploy Co-Authored-By: Claude Fable 5.1 --- apps/site/src/components/product/content/compute.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/site/src/components/product/content/compute.ts b/apps/site/src/components/product/content/compute.ts index 17d00826c33..efe50aba8cc 100644 --- a/apps/site/src/components/product/content/compute.ts +++ b/apps/site/src/components/product/content/compute.ts @@ -126,7 +126,7 @@ export const computeContent: ProductPageContent = { { name: "A preview per pushed branch", description: - "Once deploy on push is set up, every pushed branch gets its own services and its own database, built from your migrations, and deleting the branch tears them down. No shared test DB that passes tests production fails.", + "Once deploy on push is set up, every pushed branch gets its own services and its own database, and deleting the branch tears them down. A database typed by a Prisma ORM contract gets your migrations applied on deploy; one declared with rawPostgres() keeps your own migration step. No shared test DB that passes tests production fails.", illustration: "branchedStack", }, { From 3246a3c1ab98914d478ec49346c07ff9aef42f50 Mon Sep 17 00:00:00 2001 From: Gregory Boch Date: Mon, 5 Oct 2026 17:04:58 +0200 Subject: [PATCH 3/9] site: build /compute's trust line from the whole proof list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #8360 removed the market-share entry from siteConfig.proof, which left two entries. The closer's trust line read proof[2] for the GitHub stars, which is now undefined and would throw when the module loads. Build the line from every entry, the way the homepage hero and its Markdown rendition do, so it reads "Trusted by 500,000+ developers · 46,500+ GitHub stars" and no longer depends on the list's length. Co-Authored-By: Claude Fable 5.1 --- .../src/components/product/content/compute.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/site/src/components/product/content/compute.ts b/apps/site/src/components/product/content/compute.ts index efe50aba8cc..c6f3e9fd46b 100644 --- a/apps/site/src/components/product/content/compute.ts +++ b/apps/site/src/components/product/content/compute.ts @@ -41,13 +41,14 @@ import type { ProductPageContent } from "../types"; const CONSOLE = "https://console.prisma.io/sign-up"; const DOCS = "/docs"; -// The trust line the brief puts on the homepage, /compute and /postgres. Its -// numbers are siteConfig.proof's first and last entries (developers, GitHub -// stars), the same source as the homepage hero, so the pages cannot drift -// apart. The market-share entry between them stays off this page. -const developers = siteConfig.proof[0]; -const stars = siteConfig.proof[2]; -const TRUST_LINE = `Trusted by ${developers.stat} ${developers.label} · ${stars.stat} ${stars.label}`; +// The trust line the brief puts on the homepage and /compute. It is built from +// every entry of siteConfig.proof, the way hero-home.tsx and +// lib/markdown/home.ts build the homepage's proof line, so the two pages +// cannot drift apart and nothing here depends on how many entries the list +// has. +const TRUST_LINE = siteConfig.proof + .map(({ stat, label }, i) => `${i === 0 ? "Trusted by " : ""}${stat} ${label}`) + .join(" · "); export const computeContent: ProductPageContent = { name: "Prisma Compute", From 8e17749eb7bf5c69140b60315ad849ec31e408e0 Mon Sep 17 00:00:00 2001 From: Gregory Boch Date: Mon, 5 Oct 2026 17:06:06 +0200 Subject: [PATCH 4/9] site: name /compute in the Compare Prisma list's comments /compute now renders the shared list too, so the three files that say which pages carry it list /postgres, /compute and /pricing. Comments only. Co-Authored-By: Claude Fable 5.1 --- apps/site/src/components/sections/compare-links-data.ts | 6 +++--- apps/site/src/components/sections/compare-links.tsx | 6 +++--- apps/site/src/lib/markdown/compare-links.ts | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/site/src/components/sections/compare-links-data.ts b/apps/site/src/components/sections/compare-links-data.ts index 3250c65bea8..8445f580f8f 100644 --- a/apps/site/src/components/sections/compare-links-data.ts +++ b/apps/site/src/components/sections/compare-links-data.ts @@ -1,6 +1,6 @@ /** - * The hand-picked "Compare Prisma" reading list shown on /postgres and - * /pricing (sections/compare-links.tsx) and repeated in their Markdown + * The hand-picked "Compare Prisma" reading list shown on /postgres, /compute + * and /pricing (sections/compare-links.tsx) and repeated in their Markdown * renditions (lib/markdown/compare-links.ts). Plain data, no JSX, so the * Markdown modules and their node tests can import it. * @@ -18,7 +18,7 @@ export type CompareLink = { /** * The one-line intro above the list on /pricing. The list is shared between * pages; the sentence above it is not, so each page writes its own (the - * /postgres one lives in product/content/postgres.ts). Only the positioning + * /postgres and /compute ones live in product/content/). Only the positioning * sentence may repeat verbatim across pages. */ export const PRICING_COMPARE_INTRO = diff --git a/apps/site/src/components/sections/compare-links.tsx b/apps/site/src/components/sections/compare-links.tsx index e2491deca53..ff25d64a9b8 100644 --- a/apps/site/src/components/sections/compare-links.tsx +++ b/apps/site/src/components/sections/compare-links.tsx @@ -4,9 +4,9 @@ import { COMPARE_PRISMA_LINKS } from "./compare-links-data"; // The "Compare Prisma" reading list: the comparison posts and the import guide, // by their stable URLs, for the pages where someone is weighing Prisma against -// other options (/postgres and /pricing). The list is shared; the sentence -// above it comes from the page, so no paragraph repeats verbatim across pages -// (content brief). Same rhythm as sections/faq.tsx: a +// other options (/postgres, /compute and /pricing). The list is shared; the +// sentence above it comes from the page, so no paragraph repeats verbatim +// across pages (content brief). Same rhythm as sections/faq.tsx: a // centred heading, then one column of entries. The heading is literal JSX on // purpose, so markdown-parity.test.ts catches the Markdown rendition drifting // (see lib/markdown/compare-links.ts). The links cross into the blog and docs diff --git a/apps/site/src/lib/markdown/compare-links.ts b/apps/site/src/lib/markdown/compare-links.ts index cece83fcf56..91d960ce798 100644 --- a/apps/site/src/lib/markdown/compare-links.ts +++ b/apps/site/src/lib/markdown/compare-links.ts @@ -3,8 +3,8 @@ import { definitionList, heading, joinBlocks, paragraphs } from "./blocks"; /** * Markdown for sections/compare-links.tsx, shared by every page that renders - * it (/postgres and /pricing). The list itself comes from the same data module - * the section renders, so only the heading is a literal here. + * it (/postgres, /compute and /pricing). The list itself comes from the same + * data module the section renders, so only the heading is a literal here. */ /** compare-links.tsx renders this h2 above the list. */ From fc92a8d76ff05c97a7fbed810e20a1c408496a8c Mon Sep 17 00:00:00 2001 From: Gregory Boch Date: Mon, 5 Oct 2026 17:07:38 +0200 Subject: [PATCH 5/9] site: pin /compute's new meta description in the SEO metadata test scripts/seo-page-metadata.test.ts pins the meta description of each priority page, and still held the audit copy for /compute ("long-lived Bun processes", "long-running requests"). This PR replaces that description with the shared positioning sentence on purpose, so the pinned string moves with it. The page, its OG card and the llms.txt entry are checked against the new string. Co-Authored-By: Claude Fable 5.1 --- apps/site/scripts/seo-page-metadata.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/site/scripts/seo-page-metadata.test.ts b/apps/site/scripts/seo-page-metadata.test.ts index 2f65f0990ed..ddee7cc8b68 100644 --- a/apps/site/scripts/seo-page-metadata.test.ts +++ b/apps/site/scripts/seo-page-metadata.test.ts @@ -59,8 +59,12 @@ const PAGES: PageCopy[] = [ { path: "/compute", title: "Prisma Compute | Deploy TypeScript Apps and AI Agents on Bun", + // Changed on purpose in the 2026-09-30 claims pass: the audit copy said + // "long-lived" and "long-running", which the Compute docs do not back. The + // description is now the positioning sentence shared with the homepage, + // /postgres and the docs Compute index, character for character. description: - "Prisma Compute deploys TypeScript apps, APIs, and AI agents from your repo as long-lived Bun processes next to Prisma Postgres, with long-running requests and streaming. One platform for your app and its database.", + "Prisma Compute hosts TypeScript apps (Node.js, Bun or Next.js) next to Prisma Postgres on one plan. Generally available since August 2026. Free plan, no credit card. Any Postgres client works; Prisma ORM is optional.", }, { path: "/pricing", From 05242117acb364f5ebdf967ff0d82c4b2fcafcf7 Mon Sep 17 00:00:00 2001 From: Gregory Boch Date: Mon, 5 Oct 2026 17:08:57 +0200 Subject: [PATCH 6/9] site: format the co-located illustration with oxfmt oxfmt joins the "one project, one plan" paragraph onto one line. No change to what renders. Co-Authored-By: Claude Fable 5.1 --- apps/site/src/components/product/illustrations/co-located.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/site/src/components/product/illustrations/co-located.tsx b/apps/site/src/components/product/illustrations/co-located.tsx index d5e8483c482..c35492cfc14 100644 --- a/apps/site/src/components/product/illustrations/co-located.tsx +++ b/apps/site/src/components/product/illustrations/co-located.tsx @@ -42,9 +42,7 @@ export function CoLocated() { db
-

- one project, one plan -

+

one project, one plan

From 73a3bb548f45aac9a02a61235c033577129c77e3 Mon Sep 17 00:00:00 2001 From: Gregory Boch Date: Mon, 5 Oct 2026 17:10:03 +0200 Subject: [PATCH 7/9] site: write the "What does Prisma Compute not do?" answer as full sentences The answer was a run of fragments ("No WebSocket servers yet. ... No cron scheduling and no persistent filesystem."), which the staccato checker flags. The same limits, from compute/limitations.mdx ("Runtime"), now read as sentences. No fact changes. Co-Authored-By: Claude Fable 5.1 --- apps/site/src/components/product/content/compute.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/site/src/components/product/content/compute.ts b/apps/site/src/components/product/content/compute.ts index c6f3e9fd46b..a17095fe0b8 100644 --- a/apps/site/src/components/product/content/compute.ts +++ b/apps/site/src/components/product/content/compute.ts @@ -170,7 +170,7 @@ export const computeContent: ProductPageContent = { { question: "What does Prisma Compute not do?", answer: - "No WebSocket servers yet. Each service runs in one region, chosen from six. A request has 60 seconds to send its first byte, and a response that has started streaming is not cut off. No cron scheduling and no persistent filesystem. The runtime is Bun. The Compute FAQ in the docs has the full list of trade-offs.", + "Compute does not support WebSocket servers, cron scheduling or a persistent filesystem today, and each service runs in one region, chosen from six. A request has 60 seconds to send its first byte, and a response that has started streaming is not cut off. The runtime is Bun. The Compute FAQ in the docs has the full list of trade-offs.", }, { question: "Do I need Prisma ORM?", From 42f44072ae518c006d26c382ee49376382484b46 Mon Sep 17 00:00:00 2001 From: Gregory Boch Date: Mon, 5 Oct 2026 17:20:19 +0200 Subject: [PATCH 8/9] site: drop the health-check step from the /compute deploy illustration The Deploy stop of the hero tour listed a "health check / 200 OK" step, and its aria label said "a passing health check". The docs describe no health-check step for prisma deploy (cli/deploy.mdx, composer/deploying.mdx); the only one is the optional healthCheck of the Alchemy route (compute/alchemy.mdx). The step and the phrase go, and the "deployed in" row drops from 22.9s to 22.0s so it still equals the sum of the steps shown. Co-Authored-By: Claude Fable 5.1 --- .../components/product/illustrations/deploy-log.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/site/src/components/product/illustrations/deploy-log.tsx b/apps/site/src/components/product/illustrations/deploy-log.tsx index bec0a8af873..6004055575c 100644 --- a/apps/site/src/components/product/illustrations/deploy-log.tsx +++ b/apps/site/src/components/product/illustrations/deploy-log.tsx @@ -8,15 +8,17 @@ import { CardChrome, HeroPanel, StatRow } from "./parts"; // deploy does: it assembles what your build produced and does not build for // you (cli/deploy.mdx, composer/deploying.mdx), so no step here says "built". // The migrations step is what composer/databases.mdx describes for a database -// typed by a Prisma ORM contract. The timings are this build's own: they are -// not a platform performance claim, and nothing here is a latency figure. +// typed by a Prisma ORM contract. There is no health-check step: the docs +// describe one only for the Alchemy route (compute/alchemy.mdx), not for +// prisma deploy. The timings are this build's own: they are not a platform +// performance claim, and nothing here is a latency figure. The "deployed in" +// row is their sum, so change both together. const STEPS = [ { label: "read module.ts", detail: "web · api · worker", time: "0.4s" }, { label: "uploaded services", detail: "3 of 3", time: "18.2s" }, { label: "provisioned database", detail: "postgres", time: "2.1s" }, { label: "ran migrations", detail: "3 applied", time: "1.3s" }, - { label: "health check", detail: "200 OK", time: "0.9s" }, ]; function Chip({ icon: Icon, label }: { icon: typeof AppWindow; label: string }) { @@ -30,7 +32,7 @@ function Chip({ icon: Icon, label }: { icon: typeof AppWindow; label: string }) export function DeployLog() { return ( - +
- +
From 98618b5243dd75b619c302bca9f85f2ca2d7e645 Mon Sep 17 00:00:00 2001 From: Gregory Boch Date: Mon, 5 Oct 2026 17:20:19 +0200 Subject: [PATCH 9/9] site: name the build step in the /compute FAQ and scope two comments The first FAQ answer now says "Run your build, then deploy with npx prisma deploy module.ts", because deploy does not build (cli/deploy.mdx, composer/limitations.mdx). Comments only: the claims-pass note in compute.ts covers the sentences in that file, not the shared platform-stack.tsx section the page also renders, and the run-apps.tsx note cites compute/faq.mdx for the Bun runtime, which compute/limitations.mdx "Runtime" does not name. Co-Authored-By: Claude Fable 5.1 --- .../site/src/components/product/content/compute.ts | 8 +++++--- .../components/product/illustrations/run-apps.tsx | 14 +++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/apps/site/src/components/product/content/compute.ts b/apps/site/src/components/product/content/compute.ts index a17095fe0b8..501ae4ed5c7 100644 --- a/apps/site/src/components/product/content/compute.ts +++ b/apps/site/src/components/product/content/compute.ts @@ -19,8 +19,10 @@ import type { ProductPageContent } from "../types"; // four; Object Store buckets, launched 2026-07-24, were added after the // review, and the cron card left in the claims pass. // -// Claims pass, 2026-09-30: every product sentence on this page now has a line -// in apps/docs behind it. What went, and why: +// Claims pass, 2026-09-30: every product sentence in this file now has a line +// in apps/docs behind it. The shared platform-stack.tsx section, which /orm, +// /postgres and /compute all render, is not part of this pass. What went, and +// why: // - "the easiest way to host", "microsecond", "same machine", "no code // changes": superlatives and latency figures nothing in the docs states. // - "every PR", "branched from production", "branched together": previews are @@ -165,7 +167,7 @@ export const computeContent: ProductPageContent = { { question: "Can I host my existing GitHub repo with a TypeScript frontend and Node API here?", answer: - "Yes, when the frontend and the API are TypeScript services built for Node.js, Bun or Next.js. Add a Composer declaration around the server code you already have (a service.ts per service and one module.ts); the porting guide in the docs has a prompt your coding agent can write it from. Deploy with npx prisma deploy module.ts. For deploy on push, connect the repository and add the prisma/cloud-deploy-action workflow; from then on every pushed branch gets a preview with its own database.", + "Yes, when the frontend and the API are TypeScript services built for Node.js, Bun or Next.js. Add a Composer declaration around the server code you already have (a service.ts per service and one module.ts); the porting guide in the docs has a prompt your coding agent can write it from. Run your build, then deploy with npx prisma deploy module.ts. For deploy on push, connect the repository and add the prisma/cloud-deploy-action workflow; from then on every pushed branch gets a preview with its own database.", }, { question: "What does Prisma Compute not do?", diff --git a/apps/site/src/components/product/illustrations/run-apps.tsx b/apps/site/src/components/product/illustrations/run-apps.tsx index 1072b86c2f2..a5b05238f8b 100644 --- a/apps/site/src/components/product/illustrations/run-apps.tsx +++ b/apps/site/src/components/product/illustrations/run-apps.tsx @@ -12,13 +12,13 @@ import { CardChrome, HeroPanel, SectionLabel } from "./parts"; // Stop four of the /compute hero tour — "Apps". Answers the two questions the // abstraction otherwise leaves open: what you start from, and what actually -// runs here. Real: the framework and workload names, each one a line in -// compute/limitations.mdx ("Runtime"): HTTP services, streaming, background -// work between requests through the keep-awake primitives, on Bun. Cron and -// WebSocket servers are not part of this release, so they are not listed. No -// logos, since we hold no marks for these projects, so every framework is a -// text label and a shared icon. Nothing here claims a performance -// characteristic. +// runs here. Real: the framework and workload names. HTTP services, streaming +// and background work between requests through the keep-awake primitives are +// lines in compute/limitations.mdx ("Runtime"); the Bun runtime is in +// compute/faq.mdx ("Where it has trade-offs"). Cron and WebSocket servers are +// not part of this release, so they are not listed. No logos, since we hold no +// marks for these projects, so every framework is a text label and a shared +// icon. Nothing here claims a performance characteristic. const STARTERS = [ { icon: Code, name: "Hono", descriptor: "lightweight" },