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", 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..501ae4ed5c7 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,88 @@ 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 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 +// 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 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", 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 +102,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 +123,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, 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", }, { - 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 +148,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. 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?", + answer: + "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?", + 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..c35492cfc14 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,28 @@ 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..6004055575c 100644 --- a/apps/site/src/components/product/illustrations/deploy-log.tsx +++ b/apps/site/src/components/product/illustrations/deploy-log.tsx @@ -1,18 +1,24 @@ 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. 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: "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" }, ]; function Chip({ icon: Icon, label }: { icon: typeof AppWindow; label: string }) { @@ -26,7 +32,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 }) => ( @@ -90,7 +96,7 @@ export function DeployLog() {
- +
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/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-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/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. */ 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",