Skip to content

feat(seo): canonicals, per-page metadata, and OG url/type/site_name - #1087

Open
mdo wants to merge 1 commit into
seo-pinch-zoomfrom
seo-canonicals-metadata
Open

feat(seo): canonicals, per-page metadata, and OG url/type/site_name#1087
mdo wants to merge 1 commit into
seo-pinch-zoomfrom
seo-canonicals-metadata

Conversation

@mdo

@mdo mdo commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Canonicals (H1): every route was missing rel="canonical". Adds a self-referencing canonical to all docs routes and the diffshub home. Canonicals are declared per page, not in the layout, so query-string variants (e.g. /playground?theme=…) collapse onto one indexable URL without child routes inheriting the wrong canonical.
  • Per-page metadata (H2/M4/M5): fixes the trees title collision (all 10 routes shipped the identical "Trees, from Pierre"), gives every route its own title/description, and trims the 70-char /theme title to ~49 chars.
  • OG fields (M2): adds og:url, og:type, and og:site_name site-wide.
  • New apps/docs/lib/page-metadata.ts centralizes this because Next.js replaces nested openGraph/twitter objects from parent segments instead of deep-merging, so each page must restate its full card.

Excludes JSON-LD structured data and demo/pipes noindex by design (kept for separate follow-ups).

Test plan

  • Every route emits a self-referencing <link rel="canonical">
  • No two routes on any site share a <title>
  • og:url / og:type / og:site_name present site-wide
  • moonx docs:typecheck (passing) and moonx diffshub:typecheck

Stacked on #1086 (4 of 4).

Every route was missing rel=canonical, and 15 of 22 routes shared a title/description. Adds a pageMetadata helper (docs) that emits a self-referencing canonical, og:url/og:type/og:site_name, and correct per-site card images, then applies it across the docs routes; diffshub home/layout get the same OG fields and a canonical. Also fixes the trees title collision (all 10 routes shared one title) and trims the 70-char /theme title. Canonicals are declared per-page rather than in the layout so query-string variants (e.g. /playground?theme=) collapse onto one indexable URL without child routes inheriting the wrong canonical.
@vercel

vercel Bot commented Aug 19, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
pierre-diffshub Ready Ready Preview Aug 19, 2026 9:20pm
pierre-docs-diffs Ready Ready Preview Aug 19, 2026 9:20pm
pierre-docs-trees Ready Ready Preview Aug 19, 2026 9:20pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
pierrejs-diff-demo Skipped Skipped Aug 19, 2026 9:20pm

Request Review

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