AGENTS.md@apps/website · diff
git:20261020.4efca9c to git:20261020.8435d71
25 added, 8 removed. Audit A to A.
# Agent Instructions — `apps/website`
- The hosted cloud's front page at `/`. Shared app rules:
- [`apps/AGENTS.md`](../AGENTS.md).
+ The hosted cloud's front page at `/` and its changelog at `/changelog`.
+ Shared app rules: [`apps/AGENTS.md`](../AGENTS.md).
- - The page says the benefit, then proves it, and nothing else: the hero with
- the commands, then the showcase's steps, ending on the quickstart. Feature
- lists, ways in and roadmaps belong on the docs and zitadel.com.
+ - The front page says the benefit, then proves it, and nothing else: the
+ hero with the commands, then the showcase's steps, ending on the
+ quickstart. Feature lists, ways in and roadmaps belong on the docs and
+ zitadel.com.
- It ports `zitadel/new-website`'s narrative redesign
(`docs/narrative-ia-proposal.md` on that repo's
`claude/zitadel-narrative-redesign-377a49` branch) and follows that repo's
`apps/website` (Next.js App Router, Tailwind 4, its `packages/theme`), so
components move over unchanged. Keep the website's names in
`app/globals.css` (`bg-background`, `text-foreground`, `text-accent`).
- It does not use `@zitadel/design-tokens`; only the login previews paint with
them, on the login's own atoms.
## The fonts
- Load every face through `next/font/local` from `app/fonts/`, never
`next/font/google`: its build-time download has failed builds.
- Each file is the latin subset Google Fonts serves `next/font/google`, byte
for byte. Keep each SIL OFL license (`*-OFL.txt`) beside its file. APK
Futural is licensed, not open.
- To update one, take the file under `/* latin */` from the stylesheet served
to `next/font/google`'s user agent (Azeret Mono's family is
`Azeret+Mono:wght@500`):
```sh
curl -A 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36' \
'https://fonts.googleapis.com/css2?family=Arimo:wght@400..700&display=swap'
```
- `apps/docs/app/fonts/` holds the same Arimo file; update both.
## The theme
- Dark and light share one set of names in `app/globals.css`: add a color as
a token with a value on both sides, never a `white`/`black` literal.
- `app/theme.ts` sets `data-theme` before the first paint, from the header
toggle's choice or the system's; the login previews follow it.
## The logo and the favicons
- `app/logo.tsx` is the website's animated logo as inline SVG, its motion as
CSS keyframes in `app/globals.css`. A hover plays it once to the end, and
with `autoplay` it also plays now and then by itself (the header's and the
footer's); never for reduced motion. Give each copy its own `id`.
- `apps/docs/components/logo.tsx` is a copy; change the copies together.
- `public/favicons/` and `public/favicon.ico` are the cloud's favicons: the
console, the login UI and the docs link the same set, so a change here
reaches them. A single `/favicon.ico` cannot replace the light/dark set.
- `layout.tsx` imports the share image (`app/og.jpg`) and sets no
`metadataBase`: on Vercel, Next makes its URL absolute with the deployment's
host. Render it from `scripts/og.html` at 1200×630 as a JPEG (quality 88),
and change both when the hero's title, line or commands change.
## The commands and the showcase
- `app/commands.ts` feeds the hero and `/llms.txt`. The commands follow the
README's quick start; never add `--force`. When that journey changes,
change the commands and the showcase, and run them once against the
published CLI.
- Steps 1 to 4 replay a recorded session (`app/showcase/sessions.ts`).
Re-record rather than edit when what the CLI prints, the files setup writes
or the flow format change.
- `login-preview.tsx` draws each login screen from `@zitadel/components`'
atoms in the default template's English copy. When that copy or a step's
fields change, change the screens.
- The previews' light-DOM chrome (`login-preview.module.css`) follows
`packages/components/src/orchestrator/templates/layout-chrome.css`; follow
its changes.
- The atoms load through one dynamic import once the first preview nears the
viewport. `brand-tokens.ts` sets their `--zl-*` base layer from the
package's `tokens` and `cssVars`, the light side from its `tokensCss`; JSX
types are in `app/zl-elements.d.ts`.
- Every window is `app/window.tsx` and every command line
`app/command-line.tsx`; colors come from the `@theme` in `app/globals.css`.
- Next resolves `@zitadel/components` to its `dist/`, so `build` and `dev`
depend on `components:build` in moon and in turbo.
+ ## The changelog
+
+ - `app/changelog/releases.ts` reads the newest GitHub Releases when the page
+ builds and when it regenerates (`revalidate` in `page.tsx`), never per
+ visit. It parses the body `scripts/release-github.mjs` writes: change the
+ two together, and the fixture in `releases.spec.ts` with them.
+ - GitHub failing never fails a build (the page links to GitHub instead); a
+ regeneration rethrows, so the last page stays up.
+ - Render release Markdown only through `app/changelog/markdown.tsx`, as
+ elements and never as HTML: this origin also serves the console's session.
+ - The filters (`app/changelog/filter.ts`) name packages in `COMPONENTS`;
+ list a new published package there, or it shows under its bare name.
+ - `WEBSITE_GITHUB_TOKEN`, a token without permissions, lifts GitHub's
+ rate limit on Vercel's shared addresses ([runbook](../../docs/runbooks/cloud.md)).
+
## Routing
- The cloud routes only `/`, `/llms.txt`, `/_next/*`, `/favicon.ico` and
- `/favicons/*` here (repo-root [`vercel.json`](../../vercel.json)).
+ The cloud routes only `/`, `/changelog`, `/llms.txt`, `/_next/*`,
+ `/favicon.ico` and `/favicons/*` here (repo-root
+ [`vercel.json`](../../vercel.json)).
- A new page or `public/` file needs a rewrite of its own in `vercel.json`, or
the server answers it with a 404.
- Load every other asset from `/_next/`: fonts through `next/font`, images as
imports. Never use Next's metadata files (`app/icon.svg`, `opengraph-image`),
which Next serves at the root.
- Link another app with a plain `<a>` (`app/links.ts`), never `next/link`.
- `/llms.txt` (`app/llms.txt/route.ts`) links paths on the same host.
## Checks
```sh
- moon run website:typecheck website:lint website:build
+ moon run website:typecheck website:lint website:test website:build
moon run website:start # the build on port 3004
```
Vercel runs `turbo run build --filter=@zitadel/components`, then
`pnpm run build`; the Next build itself never goes through a task runner.