mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
The focused landing keeps its seven parts and adds back three: Backing under the hero (the fold gate holds "Backed by" at the first scroll), the open-source section with this build's counts, and a band for agents: sign up with a wallet, a key from POST /v1/account/keys, a top-up address from POST /v1/billing/crypto/deposit, no human. The Platform menu and its footer column lead with "Agents: get an API key in one call" again. The description says the agent path and the track record; the home cards are redrawn for the new title and every card takes address v5.
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, cheaper, faster. Pick all three.'
|
||
const DESCRIPTION =
|
||
'One API and one account for every AI model, routed by Enso. Agents sign up, get a key and top up with no human. Building business software since 2014; Techstars ’17.'
|
||
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>
|
||
)
|
||
}
|