Files
zeekayandGitHub 949608fd9d i18n: pages and components c–l draw their copy through @hanzo/i18n (#67)
Calculator, captable, careers, cloud, compare, contact and contact-sales,
customers, dashboards, dataroom, datastore, dev, download, enso,
enterprise, extension, family, integrations, investors, kai, learn,
legal and their components say their words through t() in client code,
<T> in server components and phrase() where copy is held as data; one
sentence is one key, figures and links its arguments.

Rebased on main: in every conflict main's file stands (its copy, layout
and styling) and only the wrapping is added back, including copy main
added since.

Claude-Session: https://claude.ai/code/session_015XYKLjZtDTJEnMo4eK3AFH
2026-10-30 01:15:31 -07:00

77 lines
3.9 KiB
TypeScript

'use client'
import { ArrowRight, Eye, Gauge, Lock, Network, Plug, Route, Shield } from 'lucide-react'
import { ProductLanding } from '@/components/product/ProductLanding'
import { ProductFooter } from '@/components/products/ProductFooter'
import { useI18n } from '@hanzo/i18n/react'
/**
* Hanzo Gateway, through the ONE product kit.
*
* The largest cluster left: TWELVE pages — engine, gateway, guard, ingress,
* jin, metrics, o11y, operator, sentinel, skills, telemetry, visor — at 85%+
* identical className sets, each a hero, a six-card grid and a call to action
* written out again. All twelve pass one typed props object to
* `ProductLanding`. See LLM.md, "Tailwind is NOT gone".
*
* EVERY WORD IS THE ONE THAT WAS HERE. ProductFooter came out of the final
* card's `max-w-3xl` wrapper, where it had been rendering narrower than on
* every other product page.
*/
export default function HanzoGatewayPage() {
const { t } = useI18n()
return (
<>
<ProductLanding
badge={"api.hanzo.ai"}
badgeIcon={Network}
title={"Hanzo Gateway"}
tagline={t("The trust boundary in front of the API")}
lede={t("Every request to api.hanzo.ai passes through it. It decides who the caller is: check the token against Hanzo IAM, throw away every identity header the client sent, write the canonical ones back from the verified claims, then hand the request on.")}
ctas={[
{ label: t("Read the docs"), href: "https://docs.hanzo.ai/docs/projects/hanzoai/gateway", icon: ArrowRight },
{ label: t("View on GitHub"), href: "https://github.com/hanzoai" },
]}
what={{
title: t("Nothing downstream has to ask who is calling"),
sub: t("Gateway answers that once, at the edge, so every service behind it can read an org id and believe it."),
pillars: [
{
icon: Shield,
title: t("The token is checked here"),
body: t("A JWT is validated against Hanzo IAM's JWKS before anything else reads the request. Opaque API keys aren't JWTs, so they go on to the service that issued them and it decides."),
},
{
icon: Lock,
title: t("Identity headers are written, not trusted"),
body: t("X-User-Id, X-Org-Id, X-Roles and every X-IAM-* variant are stripped from every inbound request, then written back from the verified claims — sub, owner, roles. A curl flag can't set them."),
},
{
icon: Route,
title: t("No route map, deliberately"),
body: t("For api.hanzo.ai it forwards /* straight to Hanzo Cloud, which owns the /v1 mount table. A second table here would be a second thing to keep in sync, and the first one to go stale."),
},
{
icon: Gauge,
title: t("Rate limits per caller and overall"),
body: t("Token-bucket limits by client IP and across the edge as a whole, with per-endpoint overrides in config. A rejected request gets a 429 and a Retry-After, not a dropped connection."),
},
{
icon: Eye,
title: t("Liveness that consults nothing"),
body: t("The health check answers whether the process is up and asks no backend. A probe that fails when a dependency blinks restarts a healthy process and turns one outage into two — so backends are dialed lazily and degrade per request instead."),
},
{
icon: Plug,
title: t("A hop, or no hop at all"),
body: t("Run it as its own service in front of the API, or mount it inside the cloud binary with one call. Same checks either way — one less network hop when you don't want one."),
},
],
}}
/>
<ProductFooter slug={"gateway"} name={"Gateway"} />
</>
)
}