Skip to content

feat(site): seo improvements#7731

Merged
mhartington merged 3 commits intomainfrom
seo-site
Mar 31, 2026
Merged

feat(site): seo improvements#7731
mhartington merged 3 commits intomainfrom
seo-site

Conversation

@mhartington
Copy link
Copy Markdown
Member

@mhartington mhartington commented Mar 31, 2026

Summary by CodeRabbit

  • New Features

    • Site now emits structured data (JSON‑LD) for site, pages, FAQs and collections to improve SEO and rich results.
    • New JSON‑LD component added to safely embed structured data.
  • Improvements

    • Standardized page metadata via a shared generator and added Open Graph images for major pages.
    • Updated many links and CTAs to use the https://www.prisma.io domain.
    • Injected analytics/tracking scripts in the site layout.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
blog Ready Ready Preview, Comment Mar 31, 2026 3:07am
docs Ready Ready Preview, Comment Mar 31, 2026 3:07am
eclipse Ready Ready Preview, Comment Mar 31, 2026 3:07am
site Ready Ready Preview, Comment Mar 31, 2026 3:07am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e8aea933-b55a-4d39-afd4-f75833220b03

📥 Commits

Reviewing files that changed from the base of the PR and between 88f8863 and f428a97.

📒 Files selected for processing (2)
  • apps/site/src/components/json-ld.tsx
  • apps/site/src/lib/structured-data.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/site/src/lib/structured-data.ts

Walkthrough

Adds a metadata factory and structured-data helpers, introduces a JsonLd component, normalizes base URLs to https://www.prisma.io, updates many page metadata exports to use createPageMetadata (adding path/ogImage), injects JSON-LD on events/pricing, adjusts layout (analytics scripts and nav), and updates several static links.

Changes

Cohort / File(s) Summary
Metadata refactor (pages)
apps/site/src/app/about/page.tsx, apps/site/src/app/client/page.tsx, apps/site/src/app/ecosystem/page.tsx, apps/site/src/app/event-code-of-conduct/page.tsx, apps/site/src/app/events/page.tsx, apps/site/src/app/migrate/page.tsx, apps/site/src/app/newsletter/page.tsx, apps/site/src/app/orm/page.tsx, apps/site/src/app/oss-friends/page.tsx, apps/site/src/app/partners/page.tsx, apps/site/src/app/partners/tos/page.tsx, apps/site/src/app/privacy/page.tsx, apps/site/src/app/sla/page.tsx, apps/site/src/app/stack/page.tsx, apps/site/src/app/support/page.tsx, apps/site/src/app/terms/page.tsx, apps/site/src/app/typedsql/page.tsx
Replaced inline Next.js Metadata exports and Metadata type imports with createPageMetadata(...) calls; added page-specific path and ogImage inputs. Some pages updated description text and external link targets.
Structured-data & metadata helper
apps/site/src/lib/page-metadata.ts, apps/site/src/lib/structured-data.ts, apps/site/src/lib/url.ts
Added createPageMetadata, site/FAQ/collection structured-data factories, and enhanced getBaseUrl() to validate/normalize NEXT_PUBLIC_PRISMA_URL and prefer https://www.prisma.io in production.
Json-LD component
apps/site/src/components/json-ld.tsx
Added JsonLd React component and JsonLdProps type to safely inject application/ld+json scripts (serializes and escapes JSON).
Layout, analytics, and nav changes
apps/site/src/app/layout.tsx
Injected site JSON-LD, added CookieYes/Tolt/GTM scripts, adjusted navigation URLs (several product/resource links changed to relative paths; Docs set to absolute), and removed one submenu entry.
Page-level JSON-LD injection
apps/site/src/app/events/page.tsx, apps/site/src/app/pricing/page.tsx
Events: added collection structured data and renders <JsonLd>; Pricing: added FAQ structured data and renders <JsonLd>.
URL and static data updates
apps/site/src/app/(index)/page.tsx, apps/site/src/app/api/search/route.ts, apps/site/src/components/homepage/card-section/default-logos.json, apps/site/src/data/prisma-with/nextjs.json, apps/site/src/data/support.json
Normalized/updated external links to https://www.prisma.io (logo links, docs links); cleared why_prisma.cards in nextjs.json; updated support docs link.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(site): seo improvements' directly aligns with the main objective of the changeset, which systematically implements SEO enhancements across the website through metadata management, structured data, and URL normalization.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@argos-ci
Copy link
Copy Markdown

argos-ci bot commented Mar 31, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Mar 31, 2026, 3:13 AM

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (1)
apps/site/src/lib/page-metadata.ts (1)

18-18: Improve consistency: convert OG/Twitter image URLs to explicit absolute URLs.

The canonical URL on line 18 is correctly built as an absolute URL. However, the OG and Twitter image fields (lines 33, 36, 39) pass relative paths directly, relying on implicit metadataBase resolution. While this works because metadataBase is properly configured in the root layout, inconsistent URL handling—explicit absolute vs. implicit relative—reduces code clarity and maintainability.

For consistency and explicitness, convert the ogImage parameter to an absolute URL in this helper:

Suggested refactor
 export function createPageMetadata({
   title,
   description,
   path,
   ogImage = "/og/og-index.png",
 }: PageMetadataOptions): Metadata {
   const pathname = path === "/" ? "/" : path.startsWith("/") ? path : `/${path}`;
   const url = new URL(pathname, getBaseUrl()).toString();
+  const baseUrl = getBaseUrl();
+  const ogImageUrl = ogImage
+    ? new URL(ogImage.startsWith("/") ? ogImage : `/${ogImage}`, baseUrl).toString()
+    : undefined;
 
   return {
     title,
     description,
     alternates: {
       canonical: url,
     },
     openGraph: {
       title,
       description,
       url,
       siteName: "Prisma",
       locale: "en_US",
       type: "website",
-      images: ogImage ? [{ url: ogImage }] : undefined,
+      images: ogImageUrl ? [{ url: ogImageUrl }] : undefined,
     },
     twitter: {
-      card: ogImage ? "summary_large_image" : "summary",
+      card: ogImageUrl ? "summary_large_image" : "summary",
       title,
       description,
-      images: ogImage ? [ogImage] : undefined,
+      images: ogImageUrl ? [ogImageUrl] : undefined,
     },
   };
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/lib/page-metadata.ts` at line 18, The OG/Twitter image URLs are
left as relative paths while the canonical `url` is made absolute; update the
helper to normalize `ogImage` into an explicit absolute URL by resolving it
against `getBaseUrl()` (e.g., replace usages of the raw `ogImage` parameter with
a computed absolute value using `new URL(ogImage, getBaseUrl()).toString()`),
then use that absolute value for the Open Graph and Twitter image fields so
`ogImage`, `getBaseUrl()`, and the existing `url` variable are consistently
absolute.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/site/src/app/layout.tsx`:
- Around line 155-176: The GTM bootstrap (Script with id="gmanager") and Tolt
Script (Script with data-tolt="fda67739-7ed0-42d2-b716-6da0edbec191") are loaded
unconditionally; add consent handling so they only run when CookieYes consent is
granted. Fix by adding data-cookieyes-category="analytics" to the Tolt <Script>
tag and making the GTM snippet consent-aware — either wrap the GTM injection
(Script id="gmanager" dangerouslySetInnerHTML) in a component or function that
defers insertion until CookieYes fires its consent callback, or gate both
scripts behind the CookieYes callback before rendering/injecting them.

In `@apps/site/src/app/orm/page.tsx`:
- Around line 277-280: The hero CTA Button currently uses the old redirecting
URL ("https://www.prisma.io/docs/getting-started/quickstart-prismaPostgres");
update the Button component's href to the canonical path
("https://www.prisma.io/docs/concepts/prisma-orm/quickstart/prisma-postgres") to
match the footer link and avoid redirects—apply the same change for the other
Button instance referenced around the footer area (the second Button href in the
same file).

In `@apps/site/src/components/json-ld.tsx`:
- Line 11: The inline JSON-LD uses dangerouslySetInnerHTML with
JSON.stringify(data) which can be broken by embedded "</script>" sequences;
update the rendering to sanitize the serialized JSON by escaping problematic
sequences before inserting (e.g., replace occurrences of "</script" with
"<\\/script" and optionally "<!--" / "-->" if relevant) — implement a small
helper (e.g., escapeJsonForInline or sanitizeJsonLd) and use that in place of
JSON.stringify(data) in the dangerouslySetInnerHTML assignment so the JSON-LD
string is safe against script-breakout injection.

In `@apps/site/src/data/prisma-with/nextjs.json`:
- Line 99: There are placeholder blog URLs in the JSON entries where the "url"
key is set to "https://www.prisma.io/blog/post-slug" (three occurrences); update
each of those "url" values in nextjs.json to the correct, final article URLs (or
remove the card if no URL exists), making sure the replaced links are valid and
reachable before release.

In `@apps/site/src/lib/structured-data.ts`:
- Around line 18-26: The toPlainText function decodes HTML entities in the wrong
order causing sequences like "&amp;nbsp;" to remain encoded; update the
toPlainText function to perform the &amp; replacement before other entity
replacements (move the .replace(/&amp;/g, "&") call to occur prior to
replacements for &nbsp;, &quot;, &#39;/&apos;, etc.) so that doubly-encoded
entities are fully decoded, keeping the stripping of tags and whitespace
normalization as-is.

In `@apps/site/src/lib/url.ts`:
- Around line 6-8: The code currently returns process.env.NEXT_PUBLIC_PRISMA_URL
raw; instead, in the function in apps/site/src/lib/url.ts that reads
NEXT_PUBLIC_PRISMA_URL, parse and validate it: ensure a scheme is present
(prepend "https://" if missing), construct a URL object and extract only the
origin (protocol + host + optional port) to strip any path or trailing slash,
and throw or return a safe default if the value is not a valid URL; use
process.env.NEXT_PUBLIC_PRISMA_URL as the source and replace the direct return
with this normalization/validation logic.

---

Nitpick comments:
In `@apps/site/src/lib/page-metadata.ts`:
- Line 18: The OG/Twitter image URLs are left as relative paths while the
canonical `url` is made absolute; update the helper to normalize `ogImage` into
an explicit absolute URL by resolving it against `getBaseUrl()` (e.g., replace
usages of the raw `ogImage` parameter with a computed absolute value using `new
URL(ogImage, getBaseUrl()).toString()`), then use that absolute value for the
Open Graph and Twitter image fields so `ogImage`, `getBaseUrl()`, and the
existing `url` variable are consistently absolute.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d5bef587-a3d7-4d3f-8a9c-786b26e239a1

📥 Commits

Reviewing files that changed from the base of the PR and between 7bb96f6 and 890402d.

⛔ Files ignored due to path filters (23)
  • apps/site/public/og/og-about.png is excluded by !**/*.png
  • apps/site/public/og/og-client.png is excluded by !**/*.png
  • apps/site/public/og/og-ecosystem.png is excluded by !**/*.png
  • apps/site/public/og/og-event-code-of-conduct.png is excluded by !**/*.png
  • apps/site/public/og/og-events.png is excluded by !**/*.png
  • apps/site/public/og/og-migrate.png is excluded by !**/*.png
  • apps/site/public/og/og-newsletter.png is excluded by !**/*.png
  • apps/site/public/og/og-orm.png is excluded by !**/*.png
  • apps/site/public/og/og-oss-friends.png is excluded by !**/*.png
  • apps/site/public/og/og-partners-tos.png is excluded by !**/*.png
  • apps/site/public/og/og-partners.png is excluded by !**/*.png
  • apps/site/public/og/og-prisma-stack-apollo.png is excluded by !**/*.png
  • apps/site/public/og/og-prisma-stack-express.png is excluded by !**/*.png
  • apps/site/public/og/og-prisma-stack-fastify.png is excluded by !**/*.png
  • apps/site/public/og/og-prisma-stack-graphql.png is excluded by !**/*.png
  • apps/site/public/og/og-prisma-stack-hapi.png is excluded by !**/*.png
  • apps/site/public/og/og-prisma-stack-nextjs.png is excluded by !**/*.png
  • apps/site/public/og/og-prisma-stack-react.png is excluded by !**/*.png
  • apps/site/public/og/og-privacy.png is excluded by !**/*.png
  • apps/site/public/og/og-sla.png is excluded by !**/*.png
  • apps/site/public/og/og-stack.png is excluded by !**/*.png
  • apps/site/public/og/og-terms.png is excluded by !**/*.png
  • apps/site/public/og/og-typedsql.png is excluded by !**/*.png
📒 Files selected for processing (28)
  • apps/site/src/app/(index)/page.tsx
  • apps/site/src/app/about/page.tsx
  • apps/site/src/app/api/search/route.ts
  • apps/site/src/app/client/page.tsx
  • apps/site/src/app/ecosystem/page.tsx
  • apps/site/src/app/event-code-of-conduct/page.tsx
  • apps/site/src/app/events/page.tsx
  • apps/site/src/app/layout.tsx
  • apps/site/src/app/migrate/page.tsx
  • apps/site/src/app/newsletter/page.tsx
  • apps/site/src/app/orm/page.tsx
  • apps/site/src/app/oss-friends/page.tsx
  • apps/site/src/app/partners/page.tsx
  • apps/site/src/app/partners/tos/page.tsx
  • apps/site/src/app/pricing/page.tsx
  • apps/site/src/app/privacy/page.tsx
  • apps/site/src/app/sla/page.tsx
  • apps/site/src/app/stack/page.tsx
  • apps/site/src/app/support/page.tsx
  • apps/site/src/app/terms/page.tsx
  • apps/site/src/app/typedsql/page.tsx
  • apps/site/src/components/homepage/card-section/default-logos.json
  • apps/site/src/components/json-ld.tsx
  • apps/site/src/data/prisma-with/nextjs.json
  • apps/site/src/data/support.json
  • apps/site/src/lib/page-metadata.ts
  • apps/site/src/lib/structured-data.ts
  • apps/site/src/lib/url.ts

Make metadata generation and inline JSON-LD safer while normalizing configured base URLs and gating analytics scripts on consent. Also remove placeholder Next.js article links and point ORM CTAs at the current Prisma Postgres quickstart.

Made-with: Cursor
Escape inline JSON-LD with Unicode-safe replacements to avoid script parsing issues and update FAQ plain-text normalization to handle doubly encoded entities without reintroducing unsafe general entity decoding.

Made-with: Cursor
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/site/src/app/layout.tsx (1)

80-82: Clean up trailing whitespace from removed entry.

Line 81 contains only whitespace, likely leftover from removing the "Accelerate" submenu entry. This creates unnecessary noise in the codebase.

🧹 Proposed cleanup
           url: "/studio",
             desc: "Explore and manipulate your data",
           },
-     
         ],
       },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/app/layout.tsx` around lines 80 - 82, Remove the stray
whitespace-only line left behind after the removed "Accelerate" submenu in
apps/site/src/app/layout.tsx: open the JSX/array of menu items (the closing ],
entry list or surrounding fragment) and delete the blank line that contains only
spaces so there are no trailing-whitespace-only lines; save and run the
formatter (Prettier/ESLint autofix) to ensure no trailing spaces remain.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/site/src/components/json-ld.tsx`:
- Around line 6-11: The sanitizeJsonLd function currently escapes "</script",
"<!--" and "-->" but misses the HTML5 comment end variant "--!>"; update
sanitizeJsonLd to also replace occurrences of "--!>" (e.g., .replace(/--!>/g,
"--\\!>")) so the JSON-LD string escapes that comment terminator as well,
keeping the existing replacements for "</script", "<!--", and "-->" in place.

---

Nitpick comments:
In `@apps/site/src/app/layout.tsx`:
- Around line 80-82: Remove the stray whitespace-only line left behind after the
removed "Accelerate" submenu in apps/site/src/app/layout.tsx: open the JSX/array
of menu items (the closing ], entry list or surrounding fragment) and delete the
blank line that contains only spaces so there are no trailing-whitespace-only
lines; save and run the formatter (Prettier/ESLint autofix) to ensure no
trailing spaces remain.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8560aa43-73bb-4170-a722-e3c9f9d4446f

📥 Commits

Reviewing files that changed from the base of the PR and between 890402d and 88f8863.

📒 Files selected for processing (7)
  • apps/site/src/app/layout.tsx
  • apps/site/src/app/orm/page.tsx
  • apps/site/src/components/json-ld.tsx
  • apps/site/src/data/prisma-with/nextjs.json
  • apps/site/src/lib/page-metadata.ts
  • apps/site/src/lib/structured-data.ts
  • apps/site/src/lib/url.ts
✅ Files skipped from review due to trivial changes (2)
  • apps/site/src/lib/page-metadata.ts
  • apps/site/src/lib/structured-data.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/site/src/data/prisma-with/nextjs.json
  • apps/site/src/lib/url.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants