Files
Kacper Kapuściak 5e81136096 docs: generate an Open Graph card for every page at build time (#889)
## What

Every docs page now gets its own Open Graph card, rendered during the
build.

The card is `static/img/og-background.png` with a frosted glass panel in
the middle: a 920x400
rounded rectangle with a 32px radius, the background blurred behind it
(`backdrop-filter: blur(60px)`,
an SVG `feGaussianBlur` of stdDeviation 30) and tinted with `#C3D3E033`.
The white Argent logo sits
centred on the panel, with the page title centred underneath in DM Sans
Medium at `#FFFFFF`.

Before, every page shared one static `img/logo-icon.png`.

## How

`plugins/og-image/index.js` is a Docusaurus plugin with a `postBuild`
hook. It:

1. Renders the background and the frosted panel once. That part is the
same on every card, so it is
reused as a bitmap and only the logo and the title are rendered per
page.
2. Reads each built page's `<title>`, strips the ` | Argent` suffix, and
lays out the logo and the
   title with satori. Long titles wrap and stay centred.
3. Rasterises the result with resvg into `build/img/og/<route>.png`.
4. Rewrites the `og:image` and `twitter:image` tags of that page to the
new absolute URL, and adds
   `og:image:width` / `og:image:height`.

Satori embeds every glyph as a path, so resvg needs no font lookup. DM
Sans Medium is vendored in
`scripts/og-assets/` (with its OFL license), so CI renders the cards
exactly as a local build does.

Layout, colours and blur are constants at the top of the plugin.

Pages with no title of their own get a card with the logo alone. That
covers the home page, whose
title is the site title the logo already shows, and the search page,
whose title the Algolia search
theme renders as `[object Object]`.

The shared `@swmansion/t-rex-ui` theme points doc pages at
`img/og/<title>.png` and hardcodes a
"React Native Reanimated" fallback. The plugin overwrites those tags
after the build, so the naming
is route based and consistent across doc pages, the home page, search
and 404.

## Verification

Against a clean `npx docusaurus build`, checked for all 20 built pages:
the tag is an absolute site
URL, the target exists in `build/`, it is a valid PNG at 1200x630,
`twitter:image` matches
`og:image`, the width/height tags are 1200/630, and `twitter:card` is
`summary_large_image`. No
unreferenced cards.

Serving the production build over HTTP, every card URL returns `HTTP
200` with `content-type:
image/png`.

`npm run typecheck`, `npm run build`, and the root `npm run format` and
`npm run lint` all pass.

## Notes

- The cards add ~16MB to a 65MB build, about 845KB each. The background
is a photograph and resvg
only emits PNG. Re-encoding as JPEG would bring that down to roughly 2MB
at the cost of a `sharp`
  dependency, if the deploy size becomes a concern.
- New `packages/docs` dependencies: `satori` and `@resvg/resvg-js`. Both
record all platform
  binaries in the lockfile, including `linux-x64-gnu` for the CI runner.
- The branch also carries a `docs: update favicon` commit, which
replaces `static/img/favicon.png`.

## Docs

No user facing docs change: this is build internals. The build step is
documented for contributors
in `packages/docs/CLAUDE.md`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01JovgRQBFngBsHnUYSoRF56
2026-08-21 16:31:57 +02:00

3.7 KiB

Docs site

Docusaurus site for docs.swmansion.com/argent. Content lives in docs/, grouped into fundamentals/, features/ and reference/ (each with a _category_.json for label and position).

  • features/ is a conceptual overview: what the agent can do and why it matters, in a few sentences per section, with videos. No tool tables, parameter names, enum values or selector rules. End each page with a link to the tools reference.
  • reference/ holds the hard technical details: tool names, parameters, values, limits and exact behaviour.

Writing style

All prose in docs/ is written in Simplified Technical English (ASD-STE100):

  • One idea per sentence. Keep descriptive sentences under 25 words, instructions under 20.
  • Active voice, simple present tense. "Argent records the requests", not "the requests are recorded".
  • One term for one concept, reused everywhere. Do not vary the wording for style.
  • No contractions, idioms, metaphors or humor. No implied subjects: name the actor in every sentence ("Argent removes...", "The agent reads...").
  • Instructions are imperatives: "Run the app again after the agent connects."
  • Put parallel items in a list or a table instead of a sentence with subordinate clauses.

docs/features/network.mdx is the reference for the target style.

Adding a page

Every doc page needs front matter with a lucide sidebar icon:

---
sidebar_position: 3
sidebar_label: Tools
title: Tools reference
sidebar_custom_props:
  icon: wrench
---

The icon name must also be registered in src/theme/SidebarIcon/index.tsx - import the component from lucide-react and add it to the ICONS map under its kebab-case name. Icons are imported one by one on purpose so the bundle only carries the ones the sidebar uses. An unregistered name renders nothing, silently, with no build error.

When inserting a page in the middle of a section, bump the sidebar_position of the pages that follow it.

Open Graph images

plugins/og-image/ renders one social card per page in the postBuild step and rewrites the og:image and twitter:image tags of every built HTML file to point at it. The cards land in build/img/og/ and are named after the route.

The card is static/img/og-background.png with a frosted glass panel in the middle, the white Argent logo centred on the panel, and the page title centred underneath. The title comes from the <title> of the built page, with the | Argent suffix removed.

Satori lays out the logo and the title and embeds every glyph as a path. resvg rasterises the result. The font is vendored in scripts/og-assets/, so the cards do not depend on the fonts installed on the machine. Layout, colours and blur live as constants at the top of plugins/og-image/index.js.

Checks

Run npx docusaurus build after editing docs. It fails on broken internal links, which is the main thing to catch after moving or renaming a page (also update any /docs/... links that pointed at the old path).

Run npm run format and npm run lint from the repo root after editing docs or src/. Prettier and ESLint both run from the root. The root .prettierrc and .prettierignore cover this site together with the packages. The root eslint.config.mjs lints packages/docs/ with the same type-aware rules as the packages plus the React hooks rules for src/. The root lint needs the dependencies of this package installed (npm install in this directory) because tsconfig.json extends @docusaurus/tsconfig.

The Docs build workflow runs typecheck and build on every pull request that touches packages/docs/. The Format and Lint workflows run the root Prettier and ESLint, which include this package.