diff --git a/docs/public/Geist-Regular.ttf b/docs/public/Geist-Regular.ttf new file mode 100644 index 0000000..07f9e4f Binary files /dev/null and b/docs/public/Geist-Regular.ttf differ diff --git a/docs/src/app/cdp-mode/page.mdx b/docs/src/app/cdp-mode/page.mdx index 9c5242a..7edec00 100644 --- a/docs/src/app/cdp-mode/page.mdx +++ b/docs/src/app/cdp-mode/page.mdx @@ -1,4 +1,6 @@ -export const metadata = { title: "CDP Mode" } +import { pageMetadata } from "@/lib/page-metadata" + +export const metadata = pageMetadata("cdp-mode") # CDP Mode diff --git a/docs/src/app/changelog/page.mdx b/docs/src/app/changelog/page.mdx index 5134fab..d5d8e54 100644 --- a/docs/src/app/changelog/page.mdx +++ b/docs/src/app/changelog/page.mdx @@ -1,4 +1,6 @@ -export const metadata = { title: "Changelog" } +import { pageMetadata } from "@/lib/page-metadata" + +export const metadata = pageMetadata("changelog") # Changelog diff --git a/docs/src/app/commands/page.mdx b/docs/src/app/commands/page.mdx index 82ed5f4..5e9e793 100644 --- a/docs/src/app/commands/page.mdx +++ b/docs/src/app/commands/page.mdx @@ -1,4 +1,6 @@ -export const metadata = { title: "Commands" } +import { pageMetadata } from "@/lib/page-metadata" + +export const metadata = pageMetadata("commands") # Commands diff --git a/docs/src/app/configuration/page.mdx b/docs/src/app/configuration/page.mdx index a82c36b..ff93d10 100644 --- a/docs/src/app/configuration/page.mdx +++ b/docs/src/app/configuration/page.mdx @@ -1,4 +1,6 @@ -export const metadata = { title: "Configuration" } +import { pageMetadata } from "@/lib/page-metadata" + +export const metadata = pageMetadata("configuration") # Configuration diff --git a/docs/src/app/diffing/page.mdx b/docs/src/app/diffing/page.mdx index f6fcda9..871b512 100644 --- a/docs/src/app/diffing/page.mdx +++ b/docs/src/app/diffing/page.mdx @@ -1,4 +1,6 @@ -export const metadata = { title: "Diffing" } +import { pageMetadata } from "@/lib/page-metadata" + +export const metadata = pageMetadata("diffing") import { DiffDemo } from "@/components/diff-demo" diff --git a/docs/src/app/installation/page.mdx b/docs/src/app/installation/page.mdx index fe0fbb9..f203965 100644 --- a/docs/src/app/installation/page.mdx +++ b/docs/src/app/installation/page.mdx @@ -1,4 +1,6 @@ -export const metadata = { title: "Installation" } +import { pageMetadata } from "@/lib/page-metadata" + +export const metadata = pageMetadata("installation") # Installation diff --git a/docs/src/app/ios/page.mdx b/docs/src/app/ios/page.mdx index 82e6b1d..1a40cab 100644 --- a/docs/src/app/ios/page.mdx +++ b/docs/src/app/ios/page.mdx @@ -1,4 +1,6 @@ -export const metadata = { title: "iOS Simulator" } +import { pageMetadata } from "@/lib/page-metadata" + +export const metadata = pageMetadata("ios") # iOS Simulator diff --git a/docs/src/app/layout.tsx b/docs/src/app/layout.tsx index 4d451a4..ec09015 100644 --- a/docs/src/app/layout.tsx +++ b/docs/src/app/layout.tsx @@ -21,8 +21,27 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "agent-browser", + metadataBase: new URL("https://agent-browser.dev"), + title: { + default: "agent-browser | Headless Browser Automation for AI", + template: "%s | agent-browser", + }, description: "Headless browser automation CLI for AI agents", + openGraph: { + type: "website", + locale: "en_US", + url: "https://agent-browser.dev", + siteName: "agent-browser", + title: "agent-browser | Headless Browser Automation for AI", + description: "Headless browser automation CLI for AI agents", + images: [{ url: "/og", width: 1200, height: 630, alt: "agent-browser" }], + }, + twitter: { + card: "summary_large_image", + title: "agent-browser | Headless Browser Automation for AI", + description: "Headless browser automation CLI for AI agents", + images: ["/og"], + }, }; export default async function RootLayout({ diff --git a/docs/src/app/og/[...slug]/route.tsx b/docs/src/app/og/[...slug]/route.tsx new file mode 100644 index 0000000..50ce10c --- /dev/null +++ b/docs/src/app/og/[...slug]/route.tsx @@ -0,0 +1,16 @@ +import { NextResponse } from "next/server"; +import { getPageTitle, renderOgImage } from "../og-image"; + +export async function GET( + _request: Request, + { params }: { params: Promise<{ slug: string[] }> }, +) { + const { slug } = await params; + const title = getPageTitle(slug.join("/")); + + if (!title) { + return NextResponse.json({ error: "Not found" }, { status: 404 }); + } + + return renderOgImage(title); +} diff --git a/docs/src/app/og/og-image.tsx b/docs/src/app/og/og-image.tsx new file mode 100644 index 0000000..dde4dde --- /dev/null +++ b/docs/src/app/og/og-image.tsx @@ -0,0 +1,104 @@ +import { ImageResponse } from "next/og"; +import { readFile } from "node:fs/promises"; +import { join } from "node:path"; + +export { getPageTitle } from "@/lib/page-titles"; + +let fontCache: { geistRegular: Buffer } | null = null; + +async function loadFonts() { + if (fontCache) return fontCache; + const geistRegular = await readFile( + join(process.cwd(), "public/Geist-Regular.ttf"), + ); + fontCache = { geistRegular }; + return fontCache; +} + +export async function renderOgImage(title: string) { + const { geistRegular } = await loadFonts(); + + return new ImageResponse( +