From 233f88dac243bb98db1d11f07e7644fc41cc6287 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier Date: Fri, 26 Jun 2026 16:50:08 +0200 Subject: [PATCH] fix(seo): use permanentRedirect (308) instead of redirect (307) for canonical chain URLs redirect() defaults to 307 which Google treats as temporary - the source URL stays in the index competing with the target. 308 tells Google to consolidate rank signal on the canonical lowercase URL. --- src/app/benchmarks/[slug]/[chain]/page.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app/benchmarks/[slug]/[chain]/page.tsx b/src/app/benchmarks/[slug]/[chain]/page.tsx index 26df0530..f58f92b6 100644 --- a/src/app/benchmarks/[slug]/[chain]/page.tsx +++ b/src/app/benchmarks/[slug]/[chain]/page.tsx @@ -1,5 +1,5 @@ import type { Metadata } from "next"; -import { notFound, redirect } from "next/navigation"; +import { notFound, permanentRedirect } from "next/navigation"; import Link from "next/link"; import { ArrowLeft, ArrowUpRight } from "lucide-react"; import { getBenchmark } from "@/data/benchmarks"; @@ -333,7 +333,10 @@ export default async function BenchmarkChainPage({ // and Ahrefs flags the lowercase variants as orphans (parent links use // the YAML's uppercase value). const canon = canonicalChainSlug(chain); - if (canon !== chain) redirect(`/benchmarks/${slug}/${canon}`); + // permanentRedirect emits a 308 so Google consolidates rank signal on + // the canonical lowercase URL. redirect() defaults to 307 (temporary) + // which leaves the source URL in the index competing with the canonical. + if (canon !== chain) permanentRedirect(`/benchmarks/${slug}/${canon}`); const data = await loadChainPage(slug, chain); if (!data) notFound(); const { benchmark, explainer } = data;