mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
/agents is where an agent lands: get a key (device flow or HTTP sign-up), the free tier as /v1/billing/plans states it, a first call, the MCP server for Claude Code, Codex, Cursor and Zed, Kai and its harness, a campaign draft, and how an owner pays and bounds spend. The Agents SDK page moves to /agents/sdk. The prompt an agent pastes is lib/agents.ts, drawn on /agents and written into llms.txt, which now keeps every hand-written section. robots.txt names the AI crawlers; JSON-LD carries the positioning, 2014, the founders as /about names them, and drops a SearchAction /search never answered; /.well-known/api-catalog points at the OpenAPI document. /about gains a track-record band, each line beside its source. Claude-Session: https://claude.ai/code/session_017vrVus6PPBgP5YRzKV1iqW
75 lines
3.3 KiB
TypeScript
75 lines
3.3 KiB
TypeScript
import type { Metadata } from 'next'
|
|
import Home from '@/components/home/Home'
|
|
import { ogImages, getOgImageUrl, getTwitterImages } from '@/lib/constants/og'
|
|
import { BOOT } from '@hanzo/app/lib/session'
|
|
import { RETURNED } from '@/lib/auth/returned'
|
|
import { Apex } from './_apex'
|
|
|
|
// The apex. It lives outside the (marketing) route group, so the root layout is
|
|
// all that wraps it and it carries its own header and footer.
|
|
|
|
// The title mirrors the h1's promise, so the tab, search result and first line
|
|
// of the page all set the same expectation.
|
|
const TITLE = 'Hanzo AI — Better, Faster, Cheaper. Pick Three.'
|
|
const DESCRIPTION =
|
|
"The AI operating system for business: chat, Dev, Studio and one API on every model. Building business software since 2014 for hundreds of venture-funded startups. Techstars 2017. Start free."
|
|
const IMAGE_URL = getOgImageUrl('/')
|
|
|
|
/**
|
|
* The app's addresses before they were paths, which links and bookmarks still
|
|
* carry: a conversation, `/?chat=<id>`, is `/chat/<id>` now (@hanzo/app
|
|
* lib/host `talk`), and Dev's `/?at=<place>` is `/dev?at=<place>`, which /dev
|
|
* replaces with the place's path (app/dev/_door.tsx `moved`). The document moves
|
|
* once, before anything is drawn or asked for; the id is carried as one
|
|
* encoded segment, so it can only name a conversation.
|
|
*/
|
|
const MOVED = `try{if(location.hostname==='hanzo.reviews'||location.hostname==='www.hanzo.reviews'){location.replace('/reviews')}var q=new URLSearchParams(location.search),c=q.get('chat'),a=q.get('at');if(c)location.replace('/chat/'+encodeURIComponent(c));else if(a!==null){a=a.replace(/^\\/+/,'');location.replace(a?'/dev?at='+encodeURIComponent(a):'/dev')}}catch(_){}`
|
|
|
|
export const metadata: Metadata = {
|
|
title: TITLE,
|
|
description: DESCRIPTION,
|
|
alternates: { canonical: 'https://hanzo.ai' },
|
|
openGraph: {
|
|
title: TITLE,
|
|
description: DESCRIPTION,
|
|
url: 'https://hanzo.ai',
|
|
siteName: 'Hanzo',
|
|
type: 'website',
|
|
images: ogImages(TITLE, IMAGE_URL),
|
|
},
|
|
twitter: {
|
|
card: 'summary_large_image',
|
|
title: TITLE,
|
|
description: DESCRIPTION,
|
|
images: getTwitterImages(IMAGE_URL),
|
|
},
|
|
}
|
|
|
|
/**
|
|
* The apex: the landing for a stranger, the web app for a signed-in reader.
|
|
*
|
|
* `/` is this site's search result and its share card, and every crawler that
|
|
* reads them arrives as a stranger — so the export answers with the whole
|
|
* landing and the metadata that describes it, byte for byte.
|
|
*
|
|
* A SIGNED-IN READER IS ANSWERED WITH THE APP (app/_web.tsx), in Chat; Dev is
|
|
* the same app at `/dev`. It is the same address, not a trip somewhere else, so
|
|
* a sign-in lands here, a reload stays here, and hanzo.ai typed by a member
|
|
* opens their work. An old address, `/?chat=` or `/?at=`, moves to its path (`MOVED`). `Apex` decides in
|
|
* the browser, because a static export has no server to decide with; `BOOT`
|
|
* is the landing's first child and runs before the rest of it is parsed, so the
|
|
* pitch never paints at a member while the app loads. An OAuth popup returning
|
|
* here hands its answer to its opener and closes before any of it
|
|
* (lib/auth/returned `RETURNED`).
|
|
*/
|
|
export default function Page() {
|
|
return (
|
|
<Apex>
|
|
<script dangerouslySetInnerHTML={{ __html: RETURNED }} />
|
|
<script dangerouslySetInnerHTML={{ __html: MOVED }} />
|
|
<script dangerouslySetInnerHTML={{ __html: BOOT }} />
|
|
<Home />
|
|
</Apex>
|
|
)
|
|
}
|