From 0893b1b661e9c9c512dd92fa353da1954004f224 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 7 Sep 2026 03:00:49 +0000 Subject: [PATCH] seo: repair audit findings for the home description, estate link, and title Trim the home page meta description from 192 to 129 characters so the snippet ends at "indexed by year and player" instead of being cut off, keeping the rig count and year span. og:description and twitter:description follow the same helper, so they stay identical. Add a "Suede estate directory" link to https://hub.suedeai.ai in the shared footer, beside the estate privacy policy link and styled like it, so every page links to the hub. Replace the em dash in the site title with a colon across , og:title, twitter:title, the social image alt, and the CollectionPage name so the surfaces keep matching each other. Cover the description length and the title in the SEO helper tests. --- src/app/layout.tsx | 6 +++--- src/app/opengraph-image.tsx | 2 +- src/components/footer/Footer.tsx | 8 ++++++++ src/lib/seo.ts | 6 +++--- src/lib/seo/social-metadata.ts | 2 +- tests/lib/seo.test.ts | 17 +++++++++++++++++ 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index e75c436..c7a549a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -16,7 +16,7 @@ const defaultDescription = `A compilation archive of guitarists' rigs and signal export const metadata: Metadata = { metadataBase: new URL(SITE_URL), - title: { default: 'Suede DNA — Signal Chains, Archived', template: '%s · Suede DNA' }, + title: { default: 'Suede DNA: Signal Chains, Archived', template: '%s · Suede DNA' }, description: defaultDescription, keywords: [ 'guitar rigs', @@ -41,13 +41,13 @@ export const metadata: Metadata = { locale: 'en_US', url: SITE_URL, siteName: 'Suede DNA', - title: 'Suede DNA — Signal Chains, Archived', + title: 'Suede DNA: Signal Chains, Archived', description: defaultDescription, images: [DNA_SOCIAL_IMAGE], }, twitter: { card: 'summary_large_image', - title: 'Suede DNA — Signal Chains, Archived', + title: 'Suede DNA: Signal Chains, Archived', description: defaultDescription, site: '@AISUEDE', creator: '@johnnysuede', diff --git a/src/app/opengraph-image.tsx b/src/app/opengraph-image.tsx index 3d365ad..69e68ef 100644 --- a/src/app/opengraph-image.tsx +++ b/src/app/opengraph-image.tsx @@ -4,7 +4,7 @@ import { getStats } from '@/lib/manifest'; export const runtime = 'nodejs'; export const size = { width: 1200, height: 630 }; export const contentType = 'image/png'; -export const alt = 'Suede DNA — Signal Chains, Archived'; +export const alt = 'Suede DNA: Signal Chains, Archived'; export default async function Image() { const stats = getStats(); diff --git a/src/components/footer/Footer.tsx b/src/components/footer/Footer.tsx index c4c13f0..b074916 100644 --- a/src/components/footer/Footer.tsx +++ b/src/components/footer/Footer.tsx @@ -58,6 +58,14 @@ export function Footer() { > PRIVACY ↗ </a> + <a + href="https://hub.suedeai.ai" + className="text-[color:var(--color-mute-readable)] hover:text-[color:var(--color-signal)] block mt-1" + target="_blank" + rel="noopener noreferrer" + > + Suede estate directory ↗ + </a> <a href="https://guitar.solutions" className="text-[color:var(--color-mute-readable)] hover:text-[color:var(--color-signal)] block mt-1" diff --git a/src/lib/seo.ts b/src/lib/seo.ts index 860e8eb..d6ec45e 100644 --- a/src/lib/seo.ts +++ b/src/lib/seo.ts @@ -54,11 +54,11 @@ export function artistArchiveContext( } export function homePageTitle(): string { - return 'Suede DNA — Signal Chains, Archived'; + return 'Suede DNA: Signal Chains, Archived'; } export function homePageDescription(stats: { totalRigs: number; yearMin: number; yearMax: number }): string { - return `A compilation archive of guitarists' rigs and signal chains. ${stats.totalRigs.toLocaleString()} documented setups from ${stats.yearMin} to ${stats.yearMax}, indexed by year and player, sourced from the Guitar Geek Archives on the Internet Archive.`; + return `A compilation archive of guitarists' rigs and signal chains. ${stats.totalRigs.toLocaleString()} documented setups from ${stats.yearMin} to ${stats.yearMax}, indexed by year and player.`; } /** @@ -119,7 +119,7 @@ export function homeJsonLd( return { '@context': 'https://schema.org', '@type': 'CollectionPage', - name: 'Suede DNA — Signal Chains, Archived', + name: 'Suede DNA: Signal Chains, Archived', description: homePageDescription(stats), url: siteUrl, isPartOf: { '@type': 'WebSite', name: 'Suede DNA', url: siteUrl }, diff --git a/src/lib/seo/social-metadata.ts b/src/lib/seo/social-metadata.ts index 4d4979b..6b359f6 100644 --- a/src/lib/seo/social-metadata.ts +++ b/src/lib/seo/social-metadata.ts @@ -2,5 +2,5 @@ export const DNA_SOCIAL_IMAGE = { url: '/dna-social-card.webp', width: 1200, height: 630, - alt: 'Suede DNA — Signal Chains, Archived', + alt: 'Suede DNA: Signal Chains, Archived', }; diff --git a/tests/lib/seo.test.ts b/tests/lib/seo.test.ts index 35ca886..8c82c1b 100644 --- a/tests/lib/seo.test.ts +++ b/tests/lib/seo.test.ts @@ -6,7 +6,10 @@ import { artistPageDescription, artistPageTitle, homeJsonLd, + homePageDescription, + homePageTitle, } from '../../src/lib/seo'; +import { getStats } from '../../src/lib/manifest'; import { ARTICLES } from '../../src/lib/articles-content'; import type { Artist } from '../../src/lib/manifest'; @@ -106,6 +109,20 @@ describe('SEO helpers', () => { expect(iommi.name).toContain('Black Sabbath'); }); + it('keeps the home page title free of em dashes across every surface', () => { + expect(homePageTitle()).toBe('Suede DNA: Signal Chains, Archived'); + expect(homePageTitle()).not.toContain('\u2014'); + expect(homeJsonLd('https://dna.suedeai.ai', getStats()).name).toBe(homePageTitle()); + }); + + it('keeps the home page description within the 160 character snippet limit', () => { + const description = homePageDescription(getStats()); + expect(description.length).toBeLessThanOrEqual(160); + expect(description).toContain('409'); + expect(description).toContain('1964 to 2014'); + expect(description).toMatch(/indexed by year and player\.$/); + }); + it('does not declare a list structure the home page cannot enumerate', () => { const ld = homeJsonLd('https://dna.suedeai.ai', { totalRigs: 409,