Skip to content

fix(seo): restore redirects for deleted v6 docs and repair metadata regressions - #8144

Open
ankur-arch wants to merge 4 commits into
mainfrom
seo/traffic-investigation-fixes
Open

fix(seo): restore redirects for deleted v6 docs and repair metadata regressions#8144
ankur-arch wants to merge 4 commits into
mainfrom
seo/traffic-investigation-fixes

Conversation

@ankur-arch

@ankur-arch ankur-arch commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

While investigating the reported traffic decline, we found five concrete technical SEO problems across the docs, blog, and main site. This PR fixes those problems.

The analytics context in brief: the decline shown in PostHog is larger than the real decline. PostHog became consent-gated on June 22 (#7971), so it now only counts visitors who accept analytics cookies.

Search Console, which is not affected by cookie consent, still shows a real organic decline. But rankings have broadly remained stable or improved. The remaining decline appears to come mostly from fewer search impressions and fewer clicks per impression.

This PR addresses the technical issues discovered during the investigation. It does not attempt to solve changes in search demand or search-result click behavior.

What this PR changes

1. Redirect deleted Prisma v6 documentation URLs

Problem

The May 5 v6 consolidation (#7864) removed several v6 URL trees: guides, Prisma Postgres, Accelerate, Platform, AI, and the quickstarts. Redirects were only created for the ORM section. The other URLs have returned 404 since.

Why it matters

Search Console shows some of these URLs still received search traffic, roughly 600 clicks per month in March. A redirect sends that traffic and any accumulated link value to a live page. A 404 discards both.

Change

Add 125 redirects to apps/docs/vercel.json. Each old URL maps to its exact replacement page where one exists, otherwise to the closest relevant section.

Verification

apps/docs/scripts/audit-redirects.mjs passes: 1,422 redirect rules checked against 648 live documentation routes, no broken destinations, no redirect loops, no chains returning to /docs/v6.

2. Move robots rules to the robots.txt crawlers actually read

Problem

Docs and blog are separate Next.js apps served under www.prisma.io through path prefixes (basePath). Each defines its own robots.ts, but because of the prefix those files are served at /docs/robots.txt and /blog/robots.txt. Crawlers only request /robots.txt at the root, which is served by apps/site. So the rules defined in docs and blog have never affected crawlers in production.

Why it matters

Those rules block crawling of URLs that should not be indexed: OG image endpoints, API routes, and parameterized listing URLs such as /blog?page=2.

Change

Port the rules into apps/site/src/app/robots.ts, the file behind the real /robots.txt. The ?tag= rule is intentionally not ported: blog tag pages currently redirect into /blog?tag= URLs, and blocking those would block a redirect destination. The right crawl behavior for tag URLs remains a follow-up.

Verification

The rule list is carried over unchanged apart from the ?tag= exclusion. Only the serving location changes.

3. Prevent the internal origin hosts from being indexed

Problem

The multi-zone setup uses docs.prisma.io and blog.prisma.io internally as origins behind www.prisma.io. Those hosts can also be requested directly, and they serve full copies of the same content. Neither serves a robots.txt today (both return 404 in production). Search Console shows some blog.prisma.io URLs indexed, including ?tag= and ?page= variants, with impressions and zero clicks.

Why it matters

Duplicate copies of pages compete with the canonical www.prisma.io versions in search results.

Change

Serve a robots.txt on each origin host that disallows all crawling:

  • apps/docs/src/app/robots-origin.txt/route.ts
  • apps/blog/src/app/robots-origin.txt/route.ts

Each app redirects /robots.txt to its route using a basePath: false redirect. That option matches the URL without the app's path prefix, so the redirect answers at docs.prisma.io/robots.txt rather than docs.prisma.io/docs/robots.txt. Google follows robots.txt redirects and treats the target as the host's robots file.

A redirect is used rather than a rewrite because Next.js only allows basePath: false rewrites for external destinations. The first version of this change used a rewrite and failed the docs and blog builds; the redirect form is the same mechanism both apps already use for their root redirects.

Requests that come through www.prisma.io are unaffected: www serves its own /robots.txt from apps/site, and the zone routing only forwards /docs/* and /blog/* paths to the origin apps. Redirecting the whole origin hosts to www would be the stronger fix, but the zone routing itself sends requests to those hosts, so that is not an option.

Verification

Confirmed both origin hosts return 404 for /robots.txt in production today. Verified in a local dev server that /robots.txt returns a 307 to the robots route and the target serves the disallow-all body.

4. Fix markdown versions of blog posts on www

Problem

Pages are also exposed as markdown (.md and .mdx suffixes) for AI agents and other machine consumers, and the docs HTTP headers advertise this. For blog posts this only works on the internal origin host. In production, blog.prisma.io/blog/<post>.mdx returns 200 while www.prisma.io/blog/<post>.mdx returns 404.

The cause is rewrite ordering in apps/site/next.config.mjs. Rewrites run in order, and the site's generic /:path*.mdx rule matches /blog/*.mdx before the rule that forwards blog paths to the blog app. The generic rule sends the request to the site's own llms.mdx handler, which is a stub that always returns 404.

Change

In apps/site/next.config.mjs, add forwarding rules for /blog/*.mdx and /blog/*.md ahead of the generic rule, following the same pattern as the existing docs forwarding rule next to them. Also add .md handling to the blog app so both suffixes work, matching docs.

Verification

Production probes documented the broken behavior (200 on the origin host, 404 on www for the same post). node --check passes on the modified config.

5. Fix metadata regressions

Four small, independent fixes:

  • /compute canonical URL. A canonical URL tells search engines which URL is the authoritative version of a page. /compute is the only site page that bypasses createPageMetadata() and it shipped without one. Added alternates.canonical.
  • Blog structured data logo. Every BlogPosting referenced /logo.png, which does not exist. It now uses /images/logo.svg, the asset the Organization schema already uses.
  • Missing series redirect. Rename series slug from agentic-software-development to agentic-engineering #7972 renamed the blog series slug agentic-software-development to agentic-engineering without a redirect, so the old URL returned 404. Added the redirect.
  • Production base URL guard. Docs and blog build canonical URLs, sitemap URLs, and JSON-LD IDs from getBaseUrl(). If NEXT_PUBLIC_PRISMA_URL were ever unset in production, they would fall back to the Vercel deployment hostname and stamp the wrong host into that metadata. They now fall back to https://www.prisma.io in production, matching apps/site. This is a defensive guard. There is no evidence that wrong hosts are currently being generated.

Traffic investigation: what we actually know

The short answer to "is traffic really down from 350k to 90k": no. The 350k and 90k numbers come from two different measurement regimes, so they are not comparable. Roughly, real traffic went from about 380k monthly visitors in March to an estimated 210k in July. That is still a real decline, and Search Console confirms it, but it is about half the size the dashboard suggests.

The June drop in PostHog is a tracking change (confirmed)

Since June 22 (#7971), PostHog only loads after a visitor accepts analytics cookies through CookieYes. Visitors who do not consent are no longer counted.

Every signal that cookie consent cannot affect stayed roughly flat across that date. Comparing the six weekdays before and after the change (June 16 to 21 vs June 23 to 28):

Signal Affected by consent gating? Change
PostHog visitors, www.prisma.io Yes -53%
Google Search Console clicks No -9%
PostHog visitors, console.prisma.io No -8%
Signups (console:user_signed_up) No -16%*

* The before-window includes a June 17 signup spike; the weekly signup rate stays in its normal range before and after.

Only the consent-gated metric dropped sharply. The drop also happened simultaneously across every acquisition channel including direct visits, which no search or ranking change can produce. Based on the difference between PostHog and Search Console trends, the dashboard overstates the decline by roughly 2.5x.

Search traffic is genuinely down

Search Console is unaffected by cookie consent. Comparing March to July:

  • Clicks: 200,138 to 118,356 (-41%)
  • Impressions: approximately -20%
  • Average position: improved from about 8 to about 6

Google is still showing Prisma pages frequently, and their average ranking has not broadly worsened. The larger fall in clicks cannot be explained primarily by rankings.

What appears to be driving it

Fewer clicks for the same visibility. /docs/orm/prisma-migrate/getting-started held position 4.6 with slightly higher impressions, yet clicks fell 69% (CTR 2.1% to 0.6%). The page kept appearing in roughly the same place in Google, but fewer people clicked it. The timing overlaps with Google's May 21 to June 2 core update and broader AI Overview expansion, but Search Console alone cannot establish the cause.

Fewer searches for Prisma terms. Queries such as "prisma", "prisma seed", and "prisma migrate" received 30 to 58% fewer impressions while Prisma continued to rank near the top for them. Fewer searches are happening for those terms, rather than Prisma ranking lower. Developers shifting from search to AI assistants and summer seasonality (2025 shows a similar March-to-summer dip) are plausible contributing factors, not established causes.

Validation

Investigation

  • Search Console API data reviewed from January through August
  • Compared clicks, impressions, CTR, and average position by date
  • Compared periods by page, query, and device
  • Inspected v6 URLs and origin-host URLs separately

Code

  • Redirect audit passes across 1,422 rules and 648 live docs routes
  • No broken redirect destinations, loops, or chains returning to /docs/v6
  • node --check passes for all modified next.config.mjs files
  • Production probes reproduce the documented 200/404 behavior
  • Typechecking passes for touched applications, except for existing @prisma/eclipse errors in unrelated files

Out of scope

Known issues found during the investigation, intentionally not included in this PR:

  • Blog has llms-full.txt but no llms.txt index
  • The main site's llms.mdx route is still a stub, so site pages have no markdown versions
  • Desired crawl behavior for blog ?tag= URLs needs a product/SEO decision
  • The redirect audit is not yet part of CI

Summary by CodeRabbit

  • New Features
    • Added redirects for legacy documentation and blog URLs.
    • Added Markdown and MDX content renditions for blog pages.
    • Added dedicated robots.txt policies for the blog and documentation sites.
  • Bug Fixes
    • Improved production URL fallbacks across documentation and blog pages.
    • Corrected the structured-data publisher logo URL.
    • Added canonical metadata for the Compute page.
  • SEO
    • Expanded crawler exclusions for selected documentation, blog, API, and query-parameter URLs.

…egressions

The May 5 v6 docs consolidation (309fe27) deleted ~150 indexed
/docs/v6/** pages but only added redirects for the ORM section, leaving
the rest 404ing during a period of declining search traffic. Add 125
redirect rules mapping every deleted v6 URL to its current equivalent
(exact page where one exists, section index otherwise), verified with
scripts/audit-redirects.mjs against the live route set.

Also fix three smaller regressions found in the same investigation:

- /compute shipped without a canonical URL (only page not using
  createPageMetadata)
- every BlogPosting emitted a publisher logo pointing at the
  nonexistent /logo.png; use /images/logo.svg like the site
  Organization schema
- the agentic-software-development series rename shipped without a
  redirect, 404ing the old sitemap-listed URL

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
blog Ready Ready Preview Aug 12, 2026 7:53am
docs Ready Ready Preview Aug 12, 2026 7:53am
eclipse Ready Ready Preview Aug 12, 2026 7:53am
site Ready Ready Preview Aug 12, 2026 7:53am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b4f4325d-bcc3-450e-90c3-1901b6191942

📥 Commits

Reviewing files that changed from the base of the PR and between df9e1e1 and dfc2000.

📒 Files selected for processing (12)
  • ARCHITECTURE.md
  • apps/blog/next.config.mjs
  • apps/blog/src/app/(blog)/[slug]/page.tsx
  • apps/blog/src/app/robots-origin.txt/route.ts
  • apps/blog/src/lib/url.ts
  • apps/docs/next.config.mjs
  • apps/docs/src/app/robots-origin.txt/route.ts
  • apps/docs/src/lib/urls.ts
  • apps/docs/vercel.json
  • apps/site/next.config.mjs
  • apps/site/src/app/compute/page.tsx
  • apps/site/src/app/robots.ts

Walkthrough

The pull request updates production URL fallbacks, canonical metadata, redirects, markdown rewrites, and robots routes across the blog, docs, and site applications.

Changes

Cross-app routing and metadata

Layer / File(s) Summary
Canonical URL and metadata updates
ARCHITECTURE.md, apps/blog/src/lib/url.ts, apps/docs/src/lib/urls.ts, apps/site/src/app/compute/page.tsx, apps/blog/src/app/(blog)/[slug]/page.tsx
Production URL fallbacks now use https://www.prisma.io. The compute page declares a canonical URL. Blog JSON-LD uses the SVG logo path.
Blog redirects and markdown routes
apps/blog/next.config.mjs, apps/blog/src/app/robots-origin.txt/route.ts
The blog adds robots and series redirects, .md rewrites to /llms.mdx, and a static origin robots route.
Documentation redirects and robots route
apps/docs/next.config.mjs, apps/docs/src/app/robots-origin.txt/route.ts, apps/docs/vercel.json
The docs application adds an origin robots route and permanent redirects for legacy /docs/v6 paths.
Site zone rewrites and crawl rules
apps/site/next.config.mjs, apps/site/src/app/robots.ts
The site forwards blog markdown renditions to BLOG_ORIGIN and adds docs and blog exclusions to its robots response.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: amanvarshney01

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the v6 documentation redirects and metadata fixes, which are major parts of the SEO changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch seo/traffic-investigation-fixes

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

@argos-ci

argos-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown

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

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Aug 12, 2026, 8:00 AM

…estore blog markdown renditions

Follow-ups from validating the traffic investigation against Search
Console.

The docs and blog robots.ts files render under each zone's basePath, so
their Disallow rules never reached the live www.prisma.io/robots.txt.
Port the parameter and og/api rules into the site robots.ts, which is
the only robots.txt crawlers see. The ?tag= rule is deliberately not
ported because blog tag pages 301 into /blog?tag= URLs.

Search Console shows blog.prisma.io origin-host URLs (including
?tag=/?page= variants) indexed with impressions and zero clicks, and
neither origin host serves a robots.txt at all. Add a disallow-all
robots.txt on docs.prisma.io and blog.prisma.io via basePath-free
rewrites; www traffic never reaches these routes.

Blog markdown renditions 404 on www because the site's bare /:path*.mdx
rewrite captures /blog/*.mdx before the blog zone forward and lands in
the site's stub llms.mdx route (verified in production). Forward
/blog/*.mdx and /blog/*.md to the blog zone, and teach the blog app the
.md suffix that docs already advertises in its Link headers.

Also add the production-host guard to docs and blog getBaseUrl() so
canonicals, sitemaps, and JSON-LD ids can never fall back to a Vercel
deployment hostname, matching apps/site.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Next.js only allows basePath:false rewrites for external destinations,
so the previous rewrite failed the docs and blog builds with "Invalid
rewrite found". Use a basePath:false redirect instead, which both
configs already rely on for their root redirects. Google follows
robots.txt redirects and treats the target as the host's robots file.

Verified in dev: /robots.txt returns 307 to /docs/robots-origin.txt and
the target serves the disallow-all body.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant