diff --git a/app/layout.tsx b/app/layout.tsx index 5ff1925..c2ba73f 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -4,29 +4,37 @@ import { SkipLink, ThemeColorSync, } from "@/support/theme"; -import { INDEXABLE_ROBOTS } from "@hraness/web-discovery"; import { JsonLdScript } from "@hraness/web-discovery/json-ld"; import type { Metadata, Viewport } from "next"; import type { ReactNode } from "react"; import "./globals.css"; import { PostHogAnalytics } from "./posthog-analytics"; import { websiteJsonLd } from "./seo"; -import { SITE_ORIGIN, site, socialMetadata } from "./site"; +import { SITE_ORIGIN, site } from "./site"; export const metadata: Metadata = { metadataBase: new URL(SITE_ORIGIN), title: { - default: site.title, + default: site.applicationName, template: site.titleTemplate, }, - description: site.description, applicationName: site.applicationName, - alternates: { - canonical: "/", - }, formatDetection: { address: false, email: false, telephone: false }, - robots: INDEXABLE_ROBOTS, - ...socialMetadata(site.title, site.description, "/"), + openGraph: { + type: "website", + locale: "en_US", + siteName: site.name, + images: [{ + alt: site.socialImageAlt, + height: 630, + url: "/opengraph-image", + width: 1200, + }], + }, + twitter: { + card: "summary_large_image", + images: [{ alt: site.socialImageAlt, url: "/opengraph-image" }], + }, }; export const viewport: Viewport = { diff --git a/app/metadata.test.ts b/app/metadata.test.ts index ff1fd06..3656664 100644 --- a/app/metadata.test.ts +++ b/app/metadata.test.ts @@ -53,10 +53,9 @@ describe("stripehistory.com public identity", () => { }, sitemap: `${SITE_ORIGIN}/sitemap.xml`, }); - expect(metadata.robots).toMatchObject({ index: true, follow: true }); }); - test("keeps canonical metadata on stripehistory.com", () => { + test("keeps only site-wide defaults that other routes can inherit", () => { expect(robots()).toMatchObject({ host: SITE_ORIGIN }); expect(manifest()).toMatchObject({ description: site.description, @@ -68,14 +67,26 @@ describe("stripehistory.com public identity", () => { expect(new URL(metadata.metadataBase ?? "https://invalid.example").origin).toBe( SITE_ORIGIN, ); - expect(metadata.alternates).toEqual({ canonical: "/" }); - expect(metadata.title).toEqual({ - default: site.title, - template: site.titleTemplate, + expect(metadata).toMatchObject({ + applicationName: site.applicationName, + title: { + default: site.applicationName, + template: site.titleTemplate, + }, + openGraph: { + locale: "en_US", + siteName: site.name, + type: "website", + }, }); - expect(metadata.description).toBe(site.description); - expect(metadata.openGraph?.title).toBe(site.title); - expect(metadata.twitter?.title).toBe(site.title); + expect(metadata).not.toHaveProperty("description"); + expect(metadata).not.toHaveProperty("robots"); + expect(metadata.alternates).toBeUndefined(); + expect(metadata.openGraph).not.toHaveProperty("url"); + expect(metadata.openGraph).not.toHaveProperty("title"); + expect(metadata.openGraph).not.toHaveProperty("description"); + expect(metadata.twitter).not.toHaveProperty("title"); + expect(metadata.twitter).not.toHaveProperty("description"); expect(socialImageAlt).toBe(site.socialImageAlt); }); diff --git a/app/not-found.test.ts b/app/not-found.test.ts new file mode 100644 index 0000000..fd6659a --- /dev/null +++ b/app/not-found.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, test } from "bun:test"; +import { NOINDEX_ROBOTS } from "@hraness/web-discovery"; + +import { metadata } from "./not-found"; + +describe("stripehistory.com not-found metadata", () => { + test("uses a distinct noindex page instead of the homepage identity", () => { + expect(metadata).toEqual({ + title: "Page not found", + description: "The requested Stripe history page does not exist.", + robots: NOINDEX_ROBOTS, + }); + expect(metadata.alternates).toBeUndefined(); + expect(metadata.openGraph).toBeUndefined(); + }); +}); diff --git a/app/not-found.tsx b/app/not-found.tsx index 63b9e27..a551848 100644 --- a/app/not-found.tsx +++ b/app/not-found.tsx @@ -1,15 +1,26 @@ +import { NOINDEX_ROBOTS } from "@hraness/web-discovery"; +import type { Metadata } from "next"; import Link from "next/link"; import { SiteFooter } from "./site-footer"; import { SiteHeader } from "./site-header"; +const notFoundTitle = "Page not found"; +const notFoundDescription = "The requested Stripe history page does not exist."; + +export const metadata: Metadata = { + title: notFoundTitle, + description: notFoundDescription, + robots: NOINDEX_ROBOTS, +}; + export default function NotFound() { return (
-

Page not found

-

The requested Stripe history page does not exist.

+

{notFoundTitle}

+

{notFoundDescription}

Browse Stripe company history

diff --git a/app/page.test.tsx b/app/page.test.tsx index 0d85dff..5853b7b 100644 --- a/app/page.test.tsx +++ b/app/page.test.tsx @@ -1,8 +1,10 @@ import { describe, expect, test } from "bun:test"; +import { INDEXABLE_ROBOTS } from "@hraness/web-discovery"; import { loadHistory } from "@/lib/content"; import { renderToStaticMarkup } from "react-dom/server"; import Home, { generateMetadata } from "./page"; +import { site } from "./site"; describe("canonical stripehistory.com history", () => { test("publishes root-canonical history metadata", async () => { @@ -12,6 +14,8 @@ describe("canonical stripehistory.com history", () => { expect(metadata).toMatchObject({ alternates: { canonical: "/" }, + description: site.description, + robots: INDEXABLE_ROBOTS, title: expectedTitle, }); expect(metadata.openGraph).toMatchObject({ diff --git a/app/page.tsx b/app/page.tsx index b263cd3..b6bbee4 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,4 +1,5 @@ import { loadHistory } from "@/lib/content"; +import { INDEXABLE_ROBOTS } from "@hraness/web-discovery"; import { JsonLdScript } from "@hraness/web-discovery/json-ld"; import type { Metadata } from "next"; @@ -19,6 +20,7 @@ export async function generateMetadata(): Promise { title, description: site.description, alternates: { canonical: "/" }, + robots: INDEXABLE_ROBOTS, ...socialMetadata(`${title} | ${site.domain}`, site.description, "/"), }; }