diff --git a/apps/site/public/og/og-about.png b/apps/site/public/og/og-about.png new file mode 100644 index 0000000000..5fc15a1ac6 Binary files /dev/null and b/apps/site/public/og/og-about.png differ diff --git a/apps/site/public/og/og-client.png b/apps/site/public/og/og-client.png new file mode 100644 index 0000000000..1e1b39bbc1 Binary files /dev/null and b/apps/site/public/og/og-client.png differ diff --git a/apps/site/public/og/og-ecosystem.png b/apps/site/public/og/og-ecosystem.png new file mode 100644 index 0000000000..5da9cfa299 Binary files /dev/null and b/apps/site/public/og/og-ecosystem.png differ diff --git a/apps/site/public/og/og-event-code-of-conduct.png b/apps/site/public/og/og-event-code-of-conduct.png new file mode 100644 index 0000000000..c790c64118 Binary files /dev/null and b/apps/site/public/og/og-event-code-of-conduct.png differ diff --git a/apps/site/public/og/og-events.png b/apps/site/public/og/og-events.png new file mode 100644 index 0000000000..678d9b8f64 Binary files /dev/null and b/apps/site/public/og/og-events.png differ diff --git a/apps/site/public/og/og-migrate.png b/apps/site/public/og/og-migrate.png new file mode 100644 index 0000000000..4a20d1dd3b Binary files /dev/null and b/apps/site/public/og/og-migrate.png differ diff --git a/apps/site/public/og/og-newsletter.png b/apps/site/public/og/og-newsletter.png new file mode 100644 index 0000000000..492860ef70 Binary files /dev/null and b/apps/site/public/og/og-newsletter.png differ diff --git a/apps/site/public/og/og-orm.png b/apps/site/public/og/og-orm.png new file mode 100644 index 0000000000..31bc4d446c Binary files /dev/null and b/apps/site/public/og/og-orm.png differ diff --git a/apps/site/public/og/og-oss-friends.png b/apps/site/public/og/og-oss-friends.png new file mode 100644 index 0000000000..47d8d9299c Binary files /dev/null and b/apps/site/public/og/og-oss-friends.png differ diff --git a/apps/site/public/og/og-partners-tos.png b/apps/site/public/og/og-partners-tos.png new file mode 100644 index 0000000000..b64f136470 Binary files /dev/null and b/apps/site/public/og/og-partners-tos.png differ diff --git a/apps/site/public/og/og-partners.png b/apps/site/public/og/og-partners.png new file mode 100644 index 0000000000..83695eee72 Binary files /dev/null and b/apps/site/public/og/og-partners.png differ diff --git a/apps/site/public/og/og-prisma-stack-apollo.png b/apps/site/public/og/og-prisma-stack-apollo.png new file mode 100644 index 0000000000..48e55900c7 Binary files /dev/null and b/apps/site/public/og/og-prisma-stack-apollo.png differ diff --git a/apps/site/public/og/og-prisma-stack-express.png b/apps/site/public/og/og-prisma-stack-express.png new file mode 100644 index 0000000000..10fc9e4a50 Binary files /dev/null and b/apps/site/public/og/og-prisma-stack-express.png differ diff --git a/apps/site/public/og/og-prisma-stack-fastify.png b/apps/site/public/og/og-prisma-stack-fastify.png new file mode 100644 index 0000000000..4bf6d508c7 Binary files /dev/null and b/apps/site/public/og/og-prisma-stack-fastify.png differ diff --git a/apps/site/public/og/og-prisma-stack-graphql.png b/apps/site/public/og/og-prisma-stack-graphql.png new file mode 100644 index 0000000000..fba71d8ed6 Binary files /dev/null and b/apps/site/public/og/og-prisma-stack-graphql.png differ diff --git a/apps/site/public/og/og-prisma-stack-hapi.png b/apps/site/public/og/og-prisma-stack-hapi.png new file mode 100644 index 0000000000..90fd9a87ce Binary files /dev/null and b/apps/site/public/og/og-prisma-stack-hapi.png differ diff --git a/apps/site/public/og/og-prisma-stack-nextjs.png b/apps/site/public/og/og-prisma-stack-nextjs.png new file mode 100644 index 0000000000..ca5ff0ba05 Binary files /dev/null and b/apps/site/public/og/og-prisma-stack-nextjs.png differ diff --git a/apps/site/public/og/og-prisma-stack-react.png b/apps/site/public/og/og-prisma-stack-react.png new file mode 100644 index 0000000000..72b5310bd1 Binary files /dev/null and b/apps/site/public/og/og-prisma-stack-react.png differ diff --git a/apps/site/public/og/og-privacy.png b/apps/site/public/og/og-privacy.png new file mode 100644 index 0000000000..569a472bc1 Binary files /dev/null and b/apps/site/public/og/og-privacy.png differ diff --git a/apps/site/public/og/og-sla.png b/apps/site/public/og/og-sla.png new file mode 100644 index 0000000000..0f24bf34bb Binary files /dev/null and b/apps/site/public/og/og-sla.png differ diff --git a/apps/site/public/og/og-stack.png b/apps/site/public/og/og-stack.png new file mode 100644 index 0000000000..0434cfc93d Binary files /dev/null and b/apps/site/public/og/og-stack.png differ diff --git a/apps/site/public/og/og-terms.png b/apps/site/public/og/og-terms.png new file mode 100644 index 0000000000..baf26c4b07 Binary files /dev/null and b/apps/site/public/og/og-terms.png differ diff --git a/apps/site/public/og/og-typedsql.png b/apps/site/public/og/og-typedsql.png new file mode 100644 index 0000000000..a40544d377 Binary files /dev/null and b/apps/site/public/og/og-typedsql.png differ diff --git a/apps/site/src/app/(index)/page.tsx b/apps/site/src/app/(index)/page.tsx index 5a563cc87d..0b99326bfa 100644 --- a/apps/site/src/app/(index)/page.tsx +++ b/apps/site/src/app/(index)/page.tsx @@ -163,7 +163,7 @@ export default function SiteHome() { imageUrl: "/illustrations/homepage/typesafe", imageAlt: "Type-safe queries", icon: "fa-light fa-message-text", - link: "https://prisma.io/docs/orm/prisma-client/type-safety", + link: "https://www.prisma.io/docs/orm/prisma-client/type-safety", }, { title: "Work collaboratively", diff --git a/apps/site/src/app/about/page.tsx b/apps/site/src/app/about/page.tsx index 931b3c68c0..175e509183 100644 --- a/apps/site/src/app/about/page.tsx +++ b/apps/site/src/app/about/page.tsx @@ -1,9 +1,5 @@ import Antigravity from "../../components/homepage/antigravity"; -import type { Metadata } from "next"; -import { - SITE_HOME_DESCRIPTION, - SITE_HOME_TITLE, -} from "../../lib/blog-metadata"; +import { createPageMetadata } from "@/lib/page-metadata"; import { Action, Accordion, @@ -195,7 +191,7 @@ const boxes = [ description: (

We equip developers with the right tools at every stage, whether they - are building, fortifying, or growing their + are building, fortifying, or growing their applications.

), @@ -325,10 +321,13 @@ const investors = { ], }; -export const metadata: Metadata = { - title: SITE_HOME_TITLE, - description: SITE_HOME_DESCRIPTION, -}; +export const metadata = createPageMetadata({ + title: "About Prisma | Mission, investors & open source", + description: + "Discover Prisma's mission and Data DX focus, our open-source roots, backers, and programs that help developers build faster with data.", + path: "/about", + ogImage: "/og/og-about.png", +}); export default function About() { return ( diff --git a/apps/site/src/app/api/search/route.ts b/apps/site/src/app/api/search/route.ts index 0a6931c2d8..b1dd000985 100644 --- a/apps/site/src/app/api/search/route.ts +++ b/apps/site/src/app/api/search/route.ts @@ -21,7 +21,7 @@ const storeIdentifiers = ["blog-search", "web-search"] as const; const client = mixedbreadApiKey ? new Mixedbread({ apiKey: mixedbreadApiKey }) : null; -const websiteBaseUrl = "https://prisma.io"; +const websiteBaseUrl = "https://www.prisma.io"; const blogPrefix = "/blog"; const docsPrefix = "/docs"; diff --git a/apps/site/src/app/client/page.tsx b/apps/site/src/app/client/page.tsx index 87f56a804b..d1e557f098 100644 --- a/apps/site/src/app/client/page.tsx +++ b/apps/site/src/app/client/page.tsx @@ -1,18 +1,17 @@ -import type { Metadata } from "next"; -import { - SITE_HOME_DESCRIPTION, - SITE_HOME_TITLE, -} from "../../lib/blog-metadata"; +import { createPageMetadata } from "@/lib/page-metadata"; import { Action, Button, Card } from "@prisma/eclipse"; import API from "@/components/client/api"; import { CardSection } from "@/components/homepage/card-section/card-section"; import { cn } from "@/lib/cn"; import { Technology } from "@/components/client/technology"; -export const metadata: Metadata = { - title: SITE_HOME_TITLE, - description: SITE_HOME_DESCRIPTION, -}; +export const metadata = createPageMetadata({ + title: "Prisma Client | Type-safe database client for TypeScript & Node.js", + description: + "Prisma Client is a type-safe database client for TypeScript and Node.js with autocomplete, raw SQL support, and broad database compatibility.", + path: "/client", + ogImage: "/og/og-client.png", +}); const databases = { title: "Supported Databases", diff --git a/apps/site/src/app/ecosystem/page.tsx b/apps/site/src/app/ecosystem/page.tsx index 29f5d2d36e..b53d04881f 100644 --- a/apps/site/src/app/ecosystem/page.tsx +++ b/apps/site/src/app/ecosystem/page.tsx @@ -1,10 +1,6 @@ import { EcosystemGrid } from "@/components/ecosystem/grid"; import Antigravity from "../../components/homepage/antigravity"; -import type { Metadata } from "next"; -import { - SITE_HOME_DESCRIPTION, - SITE_HOME_TITLE, -} from "../../lib/blog-metadata"; +import { createPageMetadata } from "@/lib/page-metadata"; import { Button } from "@prisma/eclipse"; import { CopyCode } from "@/components/homepage/copy-btn"; import LogoParade from "@prisma-docs/ui/components/logo-parade"; @@ -59,10 +55,13 @@ const twoCol = [ visualType: "image" as const, }, ]; -export const metadata: Metadata = { - title: SITE_HOME_TITLE, - description: SITE_HOME_DESCRIPTION, -}; +export const metadata = createPageMetadata({ + title: "Prisma Ecosystem | Community tools and ORM integrations", + description: + "Discover community-built tools, packages, and integrations for Prisma, plus support options and ways to share your project with the ecosystem.", + path: "/ecosystem", + ogImage: "/og/og-ecosystem.png", +}); export default function SiteHome() { return ( diff --git a/apps/site/src/app/event-code-of-conduct/page.tsx b/apps/site/src/app/event-code-of-conduct/page.tsx index 7edbd7e702..365653ef4c 100644 --- a/apps/site/src/app/event-code-of-conduct/page.tsx +++ b/apps/site/src/app/event-code-of-conduct/page.tsx @@ -1,4 +1,4 @@ -import type { Metadata } from "next"; +import { createPageMetadata } from "@/lib/page-metadata"; import { cocSections, cocLastUpdated, @@ -6,11 +6,13 @@ import { } from "@/data/event-code-of-conduct"; import { LegalAccordion } from "@/components/legal-accordion"; -export const metadata: Metadata = { +export const metadata = createPageMetadata({ title: "Event Code of Conduct | Prisma", description: "All attendees, speakers, sponsors, and volunteers at Prisma events are required to agree to this code of conduct.", -}; + path: "/event-code-of-conduct", + ogImage: "/og/og-event-code-of-conduct.png", +}); export default function EventCodeOfConductPage() { return ( diff --git a/apps/site/src/app/events/page.tsx b/apps/site/src/app/events/page.tsx index 857117f016..c9265e972b 100644 --- a/apps/site/src/app/events/page.tsx +++ b/apps/site/src/app/events/page.tsx @@ -1,4 +1,6 @@ -import type { Metadata } from "next"; +import { createPageMetadata } from "@/lib/page-metadata"; +import { JsonLd } from "@/components/json-ld"; +import { createCollectionPageStructuredData } from "@/lib/structured-data"; import { Badge, Button, Card, CardContent } from "@prisma/eclipse"; import Image from "next/image"; import { @@ -10,18 +12,42 @@ import { type SponsoredEvent, } from "./events-data"; -export const metadata: Metadata = { +export const metadata = createPageMetadata({ title: "Events | Prisma", description: - "Find out when the next event or Meetup is happening, at which conferences you can see Prisma folks, and explore the content from previous events.", - alternates: { - canonical: "https://www.prisma.io/events", - }, -}; + "Find upcoming Prisma events and Meetups, see where the team will be speaking, and explore recordings and resources from past events.", + path: "/events", + ogImage: "/og/og-events.png", +}); + +const eventsStructuredData = createCollectionPageStructuredData({ + path: "/events", + name: "Prisma Events", + description: + "Find upcoming Prisma events and Meetups, see where the team will be speaking, and explore recordings and resources from past events.", + items: [ + ...meetups.map((meetup) => ({ + name: meetup.title, + url: meetup.link, + description: meetup.description, + })), + ...sponsoredEvents.map((event) => ({ + name: event.name, + url: event.link, + description: "Sponsored event supported by Prisma.", + })), + ...pastEvents.map((event) => ({ + name: event.name, + url: event.link, + description: event.description, + })), + ], +}); export default function EventsPage() { return (
+ {/* Hero */}
diff --git a/apps/site/src/app/layout.tsx b/apps/site/src/app/layout.tsx index 0ebdc6ea8e..97e9fb4e99 100644 --- a/apps/site/src/app/layout.tsx +++ b/apps/site/src/app/layout.tsx @@ -1,4 +1,6 @@ import { Provider } from "@/components/provider"; +import { JsonLd } from "@/components/json-ld"; +import { createSiteStructuredData } from "@/lib/structured-data"; import { getBaseUrl } from "@/lib/url"; import "./global.css"; import { Inter } from "next/font/google"; @@ -47,6 +49,8 @@ const themeInitScript = ` })(); `; +const siteStructuredData = createSiteStructuredData(); + function baseOptions() { return { nav: { @@ -58,32 +62,27 @@ function baseOptions() { sub: [ { text: "Postgres", - url: "https://www.prisma.io/postgres", + url: "/postgres", desc: "Managed Postgres for global workloads", icon: "fa-regular fa-chart-pyramid", }, { text: "ORM", - url: "https://www.prisma.io/orm", + url: "/orm", desc: "Managed Postgres for global workloads", icon: "fa-regular fa-database", }, { text: "Studio", icon: "fa-regular fa-table", - url: "https://www.prisma.io/studio", + url: "/studio", desc: "Explore and manipulate your data", }, - { - icon: "fa-regular fa-bolt", - text: "Accelerate", - desc: "Make your database global", - url: "https://www.prisma.io/accelerate", - }, + ], }, { - url: "https://www.prisma.io/pricing", + url: "/pricing", text: "Pricing", }, { @@ -92,7 +91,7 @@ function baseOptions() { sub: [ { text: "MCP", - url: "https://www.prisma.io/mcp", + url: "/mcp", icon: "fa-regular fa-message-code", }, { @@ -113,17 +112,17 @@ function baseOptions() { }, { text: "Stack", - url: "https://www.prisma.io/stack", + url: "/stack", icon: "fa-regular fa-layer-group", }, { text: "Ecosystem", - url: "https://www.prisma.io/ecosystem", + url: "/ecosystem", icon: "fa-regular fa-globe", }, { text: "Customer stories", - url: "https://www.prisma.io/showcase", + url: "/showcase", icon: "fa-regular fa-users", }, { @@ -135,7 +134,7 @@ function baseOptions() { ], }, { - url: "/docs", + url: "https://www.prisma.io/docs", text: "Docs", }, { @@ -152,6 +151,36 @@ export default function Layout({ children }: { children: React.ReactNode }) {