This commit is contained in:
Chris Tate
2026-02-20 08:49:53 -06:00
committed by GitHub
parent 2b8a51b9a6
commit fca9d7ab5d
21 changed files with 247 additions and 15 deletions
Binary file not shown.
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "CDP Mode" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("cdp-mode")
# CDP Mode
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "Changelog" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("changelog")
# Changelog
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "Commands" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("commands")
# Commands
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "Configuration" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("configuration")
# Configuration
+3 -1
View File
@@ -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"
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "Installation" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("installation")
# Installation
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "iOS Simulator" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("ios")
# iOS Simulator
+20 -1
View File
@@ -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({
+16
View File
@@ -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);
}
+104
View File
@@ -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(
<div
style={{
width: "100%",
height: "100%",
display: "flex",
flexDirection: "column",
backgroundColor: "black",
padding: "60px 80px",
}}
>
<div
style={{
display: "flex",
alignItems: "center",
gap: "16px",
}}
>
<svg width="36" height="36" viewBox="0 0 16 16" fill="white">
<path fillRule="evenodd" clipRule="evenodd" d="M8 1L16 15H0L8 1Z" />
</svg>
<span
style={{
fontSize: 36,
color: "#666",
fontFamily: "Geist",
fontWeight: 400,
}}
>
/
</span>
<span
style={{
fontSize: 36,
fontFamily: "Geist",
fontWeight: 400,
color: "white",
}}
>
agent-browser
</span>
</div>
<div
style={{
display: "flex",
flex: 1,
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}
>
{title.split("\n").map((line, i) => (
<span
key={i}
style={{
fontSize: 72,
fontFamily: "Geist",
fontWeight: 400,
color: "white",
letterSpacing: "-0.02em",
textAlign: "center",
lineHeight: 1.2,
}}
>
{line}
</span>
))}
</div>
</div>,
{
width: 1200,
height: 630,
fonts: [
{
name: "Geist",
data: geistRegular.buffer as ArrayBuffer,
style: "normal",
weight: 400,
},
],
},
);
}
+6
View File
@@ -0,0 +1,6 @@
import { getPageTitle, renderOgImage } from "./og-image";
export async function GET() {
const title = getPageTitle("")!;
return renderOgImage(title);
}
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "agent-browser" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("")
# agent-browser
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "Profiler" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("profiler")
# Profiler
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "Quick Start" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("quick-start")
# Quick Start
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "Selectors" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("selectors")
# Selectors
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "Sessions" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("sessions")
# Sessions
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "Snapshots" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("snapshots")
# Snapshots
+3 -1
View File
@@ -1,4 +1,6 @@
export const metadata = { title: "Streaming" }
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("streaming")
# Streaming
+39
View File
@@ -0,0 +1,39 @@
import type { Metadata } from "next";
import { PAGE_TITLES } from "./page-titles";
const DESCRIPTION =
"Headless browser automation CLI for AI agents";
export function pageMetadata(slug: string): Metadata {
const title = PAGE_TITLES[slug];
if (!title) return {};
const displayTitle = title.replace(/\n/g, " ");
const fullTitle = `${displayTitle} | agent-browser`;
const ogImageUrl = slug ? `/og/${slug}` : "/og";
return {
title: displayTitle,
openGraph: {
type: "website",
locale: "en_US",
siteName: "agent-browser",
title: fullTitle,
description: DESCRIPTION,
images: [
{
url: ogImageUrl,
width: 1200,
height: 630,
alt: `${displayTitle} - agent-browser`,
},
],
},
twitter: {
card: "summary_large_image",
title: fullTitle,
description: DESCRIPTION,
images: [ogImageUrl],
},
};
}
+20
View File
@@ -0,0 +1,20 @@
export const PAGE_TITLES: Record<string, string> = {
"": "Headless Browser\nAutomation for AI",
installation: "Installation",
"quick-start": "Quick Start",
commands: "Commands",
configuration: "Configuration",
selectors: "Selectors",
snapshots: "Snapshots",
sessions: "Sessions",
diffing: "Diffing",
"cdp-mode": "CDP Mode",
streaming: "Streaming",
profiler: "Profiler",
ios: "iOS Simulator",
changelog: "Changelog",
};
export function getPageTitle(slug: string): string | null {
return slug in PAGE_TITLES ? PAGE_TITLES[slug]! : null;
}