fix(seo): restore redirects for deleted v6 docs and repair metadata regressions - #8144
Conversation
…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>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (46)
🚧 Files skipped from review as they are similar to previous changes (11)
Included review availability: 4 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour. WalkthroughThe pull request updates production URL fallbacks, canonical metadata, redirects, Markdown rewrites, and robots routes across the blog, docs, and site applications. ChangesCross-app routing and metadata
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The PR restores redirects and metadata behavior across the site, docs, and blog, with no actionable merge-blocking risk remaining beyond normal checks and review. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 44 files. (2 skipped: 2 unsupported.) Full details: Title checkExplanation The title clearly identifies the primary SEO changes: restoring redirects for deleted v6 documentation and fixing metadata regressions. It is concise and specific, although it does not mention the robots.txt and blog forwarding changes, which are secondary objectives.
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
|
The latest updates on your projects. Learn more about Argos notifications ↗︎ Awaiting the start of a new Argos build… |
…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>
…oved by the rebrand The rebrand (#8142) rewrote every static site page with a bare metadata object, so no www.prisma.io page (including the homepage) has emitted a canonical link since it shipped. Add alternates.canonical to all 34 pages that bypass createPageMetadata, plus a metadata export on the homepage. The rebrand also removed /docs/postgres/database/local-development, which still receives ~135 search clicks and 50k impressions a month, and direct-connections, both linked from several release posts. Redirect them to their replacement pages and repoint the v6 rules at the same targets. Also cover /docs/v7, the legacy /docs/getting-started/prisma-orm tree, and a lowercased blog slug, all of which show up as 404 pageviews in PostHog.
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
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 showed these URLs still receiving roughly 600 clicks per month in March. By August Google had dropped nearly all of them from results (3 v6 URLs left, 0 clicks), so the redirects mostly recover inbound link value and stop the remaining impressions from landing on a 404, rather than recovering traffic.
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.mjspasses: 1,427 redirect rules checked against 686 live documentation routes, no broken destinations, no redirect loops, no chains returning to/docs/v6. The v6 rules were re-checked after merging the Prisma 8 docs tree from main.2. Move robots rules to the robots.txt crawlers actually read
Problem
Docs and blog are separate Next.js apps served under
www.prisma.iothrough path prefixes (basePath). Each defines its ownrobots.ts, but because of the prefix those files are served at/docs/robots.txtand/blog/robots.txt. Crawlers only request/robots.txtat the root, which is served byapps/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.ioandblog.prisma.iointernally as origins behindwww.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 someblog.prisma.ioURLs indexed, including?tag=and?page=variants, with impressions and zero clicks.Why it matters
Duplicate copies of pages compete with the canonical
www.prisma.ioversions in search results.Change
Serve a robots.txt on each origin host that disallows all crawling:
apps/docs/src/app/robots-origin.txt/route.tsapps/blog/src/app/robots-origin.txt/route.tsEach app redirects
/robots.txtto its route using abasePath: falseredirect. That option matches the URL without the app's path prefix, so the redirect answers atdocs.prisma.io/robots.txtrather thandocs.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: falserewrites 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.ioare unaffected: www serves its own/robots.txtfromapps/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.txtin production today. Verified in a local dev server that/robots.txtreturns 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 (
.mdand.mdxsuffixes) 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>.mdxreturns 200 whilewww.prisma.io/blog/<post>.mdxreturns 404.The cause is rewrite ordering in
apps/site/next.config.mjs. Rewrites run in order, and the site's generic/:path*.mdxrule matches/blog/*.mdxbefore the rule that forwards blog paths to the blog app. The generic rule sends the request to the site's ownllms.mdxhandler, which is a stub that always returns 404.Change
In
apps/site/next.config.mjs, add forwarding rules for/blog/*.mdxand/blog/*.mdahead of the generic rule, following the same pattern as the existing docs forwarding rule next to them. Also add.mdhandling 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 --checkpasses on the modified config.5. Restore canonical URLs on the main site
Problem
A canonical URL tells search engines which URL is the authoritative version of a page. The rebrand (#8142) rewrote every static site page with a bare
metadataobject instead ofcreatePageMetadata(), so since it shipped nowww.prisma.iopage has emitted a<link rel="canonical">. Confirmed in production:/,/orm,/compute,/pricing,/postgresand/stackall render without one, while docs pages still do. The original version of this PR only fixed/compute, which at the time was the single page missing it.Change
Add
alternates.canonicalto the 34 site pages that bypasscreatePageMetadata()and a metadata export on the homepage. Paths are relative and resolve against the root layout'smetadataBase, so they followgetBaseUrl()like the rest of the site.6. Redirect pages the rebrand removed
Problem
#8142 also deleted
/docs/postgres/database/local-developmentand/docs/postgres/database/direct-connectionswithout redirects. The local development page is the single largest live 404 on the site: about 135 search clicks and 50,000 impressions in the last 28 days, and it is linked from five release posts on the blog. PostHog's 404 pageviews for the last 28 days also surface/docs/v7, the legacy/docs/getting-started/prisma-orm/*tree (linked from older blog posts), and a lowercased copy of a blog slug.Change
Redirect both Prisma Postgres pages to their replacements (
/docs/local-development/postgresand/docs/postgres/database/connecting-to-your-database) and repoint the v6 rules at the same targets. Add/docs/v7to/docs/orm/v7, a prefix rule for the legacy getting-started tree, and the lowercased blog slug.7. Fix remaining metadata regressions
Three small, independent fixes:
BlogPostingreferenced/logo.png, which does not exist. It now uses/images/logo.svg, the asset the Organization schema already uses.agentic-software-developmenttoagentic-engineeringwithout a redirect, so the old URL returned 404. Added the redirect.getBaseUrl(). IfNEXT_PUBLIC_PRISMA_URLwere 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 tohttps://www.prisma.ioin production, matchingapps/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):
www.prisma.ioconsole.prisma.ioconsole:user_signed_up)* 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 1 to 28 with July 29 to August 25:
Through July the picture was fewer clicks at stable rankings. The August data adds a rankings component on desktop, which is where 90% of clicks come from. That overlaps with the Prisma 8 docs cutover and the rebrand (both mid-August), and two of the defects this PR fixes (site pages without canonicals, a high-traffic docs page 404ing) date from the same change. Search Console alone cannot separate the two, so this PR fixes the defects and leaves the attribution open.
What appears to be driving it
Fewer clicks for the same visibility.
/docs/orm/prisma-migrate/getting-startedheld 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
Code
/docs/v6node --checkpasses for all modifiednext.config.mjsfilesOut of scope
Known issues found during the investigation, intentionally not included in this PR:
llms-full.txtbut nollms.txtindexllms.mdxroute is still a stub, so site pages have no markdown versions?tag=URLs needs a product/SEO decision/docs/guides/upgrade-prisma-orm/v8gets a steady trickle of visits but no such guide exists yetSummary by CodeRabbit