From a186f9e91e9594e253c569cc71c61d110ad3ab9d Mon Sep 17 00:00:00 2001 From: Marc LeBlanc <7050295+marcleblanc2@users.noreply.github.com> Date: Thu, 17 Sep 2026 04:30:43 -0600 Subject: [PATCH] fix/seo: Emit a per-page canonical URL Every docs page shipped , so search engines treat all 500+ pages as duplicates of the landing page. generateMetadata now sets alternates.canonical to the page's own path; metadataBase in layout.tsx resolves it to an absolute URL. Found by the docs site audit in https://ampcode.com/threads/T-01a0ae50-f7f0-779c-aa66-3887c9953e33 Amp-Thread-ID: https://ampcode.com/threads/T-01a0aed2-5fbe-7768-85ea-1378bf98f9ff Co-authored-by: Amp --- src/app/[...slug]/page.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/[...slug]/page.tsx b/src/app/[...slug]/page.tsx index 01681c596..3bc78c815 100644 --- a/src/app/[...slug]/page.tsx +++ b/src/app/[...slug]/page.tsx @@ -31,6 +31,10 @@ export const generateMetadata = async ({params}: Props) => { const ogImageUrl = `${process.env.NEXT_PUBLIC_DOCS_BASE_PATH || ''}/api/og/${path}`; return { title, + // The root layout's canonical is the landing page; without this + // override every docs page tells search engines it is a duplicate + // of https://sourcegraph.com/docs. + alternates: {canonical: `/docs${post.url}`}, openGraph: { images: [{url: ogImageUrl, width: 1200, height: 630}] },