-
Notifications
You must be signed in to change notification settings - Fork 0
[codex] Update marketing pages and docs navigation #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
12af16e
ba6765a
bfca489
b41eb2c
5996d6f
a44b804
a3e175d
474e81f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| import type { Metadata } from 'next'; | ||
| import Link from 'next/link'; | ||
|
|
||
| import { SiteFooter } from '../../components/SiteFooter'; | ||
| import { SiteNav } from '../../components/SiteNav'; | ||
| import { HOME_OG_IMAGE_PATH, ogImage } from '../../lib/og-meta'; | ||
| import { absoluteUrl } from '../../lib/site'; | ||
| import s from '../landing.module.css'; | ||
|
|
||
| export const metadata: Metadata = { | ||
| title: 'About Agent Relay', | ||
| description: 'Agent Relay exists for an agent-centered future where software works through coordinated agents.', | ||
| alternates: { | ||
| canonical: absoluteUrl('/about'), | ||
| }, | ||
| openGraph: { | ||
| title: 'About Agent Relay', | ||
| description: 'Agent Relay exists for an agent-centered future where software works through coordinated agents.', | ||
| url: absoluteUrl('/about'), | ||
| type: 'website', | ||
| images: [ogImage(HOME_OG_IMAGE_PATH, 'About Agent Relay')], | ||
| }, | ||
| twitter: { | ||
| card: 'summary_large_image', | ||
| title: 'About Agent Relay', | ||
| description: 'Agent Relay exists for an agent-centered future where software works through coordinated agents.', | ||
| images: [absoluteUrl(HOME_OG_IMAGE_PATH)], | ||
| }, | ||
| }; | ||
|
|
||
| export default function AboutPage() { | ||
| const navGetStartedLink = ( | ||
| <Link href="/docs" className={`${s.ctaPrimary} ${s.homeNavAction}`}> | ||
| Get Started | ||
| </Link> | ||
| ); | ||
| const mobileGetStartedLink = ( | ||
| <Link href="/docs" className={`${s.ctaPrimary} ${s.homeNavAction}`}> | ||
| Get Started | ||
| </Link> | ||
| ); | ||
|
|
||
| return ( | ||
| <div className={`${s.page} ${s.homePage} ${s.aboutPage}`}> | ||
| <SiteNav actions={navGetStartedLink} mobileMenuContent={mobileGetStartedLink} hideLinks /> | ||
|
|
||
| <main className={s.aboutMain}> | ||
| <section className={s.aboutHero} aria-labelledby="about-title"> | ||
| <div className={s.aboutHeroCopy}> | ||
| <h1 id="about-title" className={s.aboutTitle}> | ||
| The future is <span className={s.aboutNoBreak}>agent-centered.</span> | ||
| </h1> | ||
| <p className={s.aboutLead}> | ||
| Software is becoming a network of agents that work with people, share context, and move work | ||
| forward. | ||
| </p> | ||
| </div> | ||
|
|
||
| <div className={s.aboutOrbit} role="img" aria-label="Agent Relay at the center of agent work"> | ||
| <span className={`${s.aboutOrbitRing} ${s.aboutOrbitRingOuter}`} /> | ||
| <span className={`${s.aboutOrbitRing} ${s.aboutOrbitRingInner}`} /> | ||
| <span className={`${s.aboutOrbitNode} ${s.aboutOrbitNodeTop}`}>People</span> | ||
| <span className={`${s.aboutOrbitNode} ${s.aboutOrbitNodeRight}`}>Tools</span> | ||
| <span className={`${s.aboutOrbitNode} ${s.aboutOrbitNodeBottom}`}>Memory</span> | ||
| <span className={`${s.aboutOrbitNode} ${s.aboutOrbitNodeLeft}`}>Files</span> | ||
| <span className={s.aboutOrbitCore}> | ||
| <img src="/brand-kit/agent-relay-mark-transparent.png" alt="" className={s.aboutOrbitMark} /> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using a native |
||
| </span> | ||
| </div> | ||
| </section> | ||
|
|
||
| <section className={s.aboutBeliefs} aria-labelledby="belief-title"> | ||
| <div className={s.aboutBeliefIntro}> | ||
| <h2 id="belief-title">We are building for the next center of work.</h2> | ||
| <p> | ||
| Agents need the same primitives teams rely on: identity, communication, files, memory, and | ||
| permissions. | ||
| </p> | ||
| </div> | ||
|
|
||
| <div className={s.aboutBeliefList}> | ||
| <article className={s.aboutBeliefItem}> | ||
| <h3>Agents become participants.</h3> | ||
| <p>They should join workspaces, understand context, and coordinate without brittle glue.</p> | ||
| </article> | ||
| <article className={s.aboutBeliefItem}> | ||
| <h3>Context becomes infrastructure.</h3> | ||
| <p>The history of work should be shared, searchable, durable, and easy to inspect.</p> | ||
| </article> | ||
| <article className={s.aboutBeliefItem}> | ||
| <h3>Humans stay in charge.</h3> | ||
| <p>Agent systems should make decisions visible and give people clear control points.</p> | ||
| </article> | ||
| </div> | ||
| </section> | ||
|
|
||
| <section className={s.aboutClosing} aria-label="Agent Relay purpose"> | ||
| <p>Agent Relay exists to make that future reliable, open, and understandable.</p> | ||
| </section> | ||
| </main> | ||
|
|
||
| <SiteFooter /> | ||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| import type { Metadata } from 'next'; | ||
| import Link from 'next/link'; | ||
|
|
||
| import { SiteFooter } from '../../components/SiteFooter'; | ||
| import { SiteNav } from '../../components/SiteNav'; | ||
| import { HOME_OG_IMAGE_PATH, ogImage } from '../../lib/og-meta'; | ||
| import { absoluteUrl } from '../../lib/site'; | ||
| import s from '../landing.module.css'; | ||
|
|
||
| export const metadata: Metadata = { | ||
| title: 'Careers', | ||
| description: 'Careers at Agent Relay.', | ||
| alternates: { | ||
| canonical: absoluteUrl('/careers'), | ||
| }, | ||
| openGraph: { | ||
| title: 'Careers', | ||
| description: 'Careers at Agent Relay.', | ||
| url: absoluteUrl('/careers'), | ||
| type: 'website', | ||
| images: [ogImage(HOME_OG_IMAGE_PATH, 'Careers')], | ||
| }, | ||
| twitter: { | ||
| card: 'summary_large_image', | ||
| title: 'Careers', | ||
| description: 'Careers at Agent Relay.', | ||
| images: [absoluteUrl(HOME_OG_IMAGE_PATH)], | ||
| }, | ||
| }; | ||
|
|
||
| export default function CareersPage() { | ||
| const navGetStartedLink = ( | ||
| <Link href="/docs" className={`${s.ctaPrimary} ${s.homeNavAction}`}> | ||
| Get Started | ||
| </Link> | ||
| ); | ||
| const mobileGetStartedLink = ( | ||
| <Link href="/docs" className={`${s.ctaPrimary} ${s.homeNavAction}`}> | ||
| Get Started | ||
| </Link> | ||
| ); | ||
|
|
||
| return ( | ||
| <div className={`${s.page} ${s.homePage}`}> | ||
| <SiteNav actions={navGetStartedLink} mobileMenuContent={mobileGetStartedLink} hideLinks /> | ||
|
|
||
| <main className={s.homeMain} /> | ||
|
|
||
| <SiteFooter /> | ||
| </div> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import { ImageResponse } from 'next/og'; | ||
| import { notFound } from 'next/navigation'; | ||
|
|
||
| import { DefaultVariant, loadBrandFonts, OG_SIZE } from '../../../../../lib/og/template'; | ||
| import { getProductDoc, getProductDocSlugs } from '../../../../../lib/product-docs'; | ||
| import { agentsSection } from '../../../../../lib/product-docs-nav'; | ||
|
|
||
| export const runtime = 'nodejs'; | ||
| export const dynamic = 'force-static'; | ||
|
|
||
| type RouteContext = { | ||
| params: Promise<{ slug: string }>; | ||
| }; | ||
|
|
||
| export function generateStaticParams() { | ||
| return getProductDocSlugs(agentsSection).map((slug) => ({ slug })); | ||
| } | ||
|
|
||
| export async function GET(_request: Request, { params }: RouteContext) { | ||
| const { slug } = await params; | ||
| const doc = getProductDoc(agentsSection.id, slug); | ||
|
|
||
| if (!doc) { | ||
| notFound(); | ||
| } | ||
|
|
||
| const { fonts, headingFamily, bodyFamily } = await loadBrandFonts(); | ||
|
|
||
| return new ImageResponse( | ||
| <DefaultVariant | ||
| headingFamily={headingFamily} | ||
| bodyFamily={bodyFamily} | ||
| eyebrow={agentsSection.label} | ||
| title={doc.frontmatter.title} | ||
| subtitle={doc.frontmatter.description} | ||
| />, | ||
| { | ||
| ...OG_SIZE, | ||
| ...(fonts.length > 0 ? { fonts } : {}), | ||
| } | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| import type { Metadata } from 'next'; | ||
|
|
||
| import { ProductDocPage } from '../../../../components/docs/ProductDocPage'; | ||
| import { ogImage } from '../../../../lib/og-meta'; | ||
| import { | ||
| agentsSection, | ||
| getProductDoc, | ||
| getProductDocMarkdownUrl, | ||
| getProductDocSlugs, | ||
| } from '../../../../lib/product-docs'; | ||
| import { absoluteUrl } from '../../../../lib/site'; | ||
|
|
||
| const SECTION_ID = agentsSection.id; | ||
|
|
||
| type PageProps = { | ||
| params: Promise<{ slug: string }>; | ||
| }; | ||
|
|
||
| export function generateStaticParams() { | ||
| return getProductDocSlugs(agentsSection).map((slug) => ({ slug })); | ||
| } | ||
|
|
||
| export async function generateMetadata({ params }: PageProps): Promise<Metadata> { | ||
| const { slug } = await params; | ||
| const doc = getProductDoc(SECTION_ID, slug); | ||
|
|
||
| if (!doc) { | ||
| return { title: 'Not Found' }; | ||
| } | ||
|
|
||
| const ogPath = `/docs/${SECTION_ID}/${slug}/og.png`; | ||
|
|
||
| return { | ||
| title: `${doc.frontmatter.title} — Agents`, | ||
| description: doc.frontmatter.description, | ||
| alternates: { | ||
| canonical: absoluteUrl(`/docs/${SECTION_ID}/${slug}`), | ||
| types: { 'text/markdown': getProductDocMarkdownUrl(SECTION_ID, slug) }, | ||
| }, | ||
| openGraph: { | ||
| title: `${doc.frontmatter.title} — Agents`, | ||
| description: doc.frontmatter.description, | ||
| url: absoluteUrl(`/docs/${SECTION_ID}/${slug}`), | ||
| type: 'article', | ||
| images: [ogImage(ogPath, `${doc.frontmatter.title} — Agents docs`)], | ||
| }, | ||
| twitter: { | ||
| card: 'summary_large_image', | ||
| title: `${doc.frontmatter.title} — Agents`, | ||
| description: doc.frontmatter.description, | ||
| images: [absoluteUrl(ogPath)], | ||
| }, | ||
| }; | ||
| } | ||
|
|
||
| export default async function AgentsDocPage({ params }: PageProps) { | ||
| const { slug } = await params; | ||
| return <ProductDocPage sectionId={SECTION_ID} slug={slug} />; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { agentsSection, getProductDocMarkdown, getProductDocSlugs } from '../../../../../lib/product-docs'; | ||
|
|
||
| export const revalidate = 86400; | ||
| export const dynamicParams = false; | ||
|
|
||
| export function generateStaticParams() { | ||
| return getProductDocSlugs(agentsSection).map((slug) => ({ slug: `${slug}.md` })); | ||
| } | ||
|
|
||
| type RouteProps = { | ||
| params: Promise<{ slug: string }>; | ||
| }; | ||
|
|
||
| export async function GET(_request: Request, { params }: RouteProps) { | ||
| const { slug: rawSlug } = await params; | ||
| const slug = rawSlug.replace(/\.md$/, ''); | ||
|
|
||
| const doc = getProductDocMarkdown(agentsSection.id, slug); | ||
|
|
||
| if (!doc) { | ||
| return new Response('Not found', { status: 404 }); | ||
| } | ||
|
|
||
| return new Response(doc.markdown, { | ||
| headers: { | ||
| 'Content-Type': 'text/markdown; charset=utf-8', | ||
| 'Cache-Control': 'public, max-age=86400', | ||
| }, | ||
| }); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| import { redirect } from 'next/navigation'; | ||
|
|
||
| export default function AgentsDocsIndexPage() { | ||
| redirect('/docs/agents/introduction'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is redundant code duplication where
navGetStartedLinkandmobileGetStartedLinkare defined as two separate but completely identical JSX elements. We can consolidate them into a singlegetStartedLinkvariable and pass it to both props in<SiteNav />. This simplifies the component and improves maintainability.