docs Full documentation content. \[!IMPORTANT] > > Variables default to `""` (empty) unless a fallback is documented below. | var | description | example | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | | `MDX`\* | Path to `*.mdx` folder NB: can be relative or absolute | `docs` or `~/code/myproject/documentation` | | `DOCS_CONFIG` | Path to the component and data configuration, relative to the current working directory or absolute. Unset: look for `docs.config.ts` there; no file keeps the built-in renderer. CLI: `--config` overrides this variable. | `config/docs.config.ts` | | `NEXT_PUBLIC_LIBNAME`\* | Library name | `React Three Fiber` | | `NEXT_PUBLIC_LIBNAME_SHORT` | Library short name | `r3f` | | `BASE_PATH` | Base path for the final URL | `/react-three-fiber` | | `HOME_REDIRECT` | Where the home should redirect | `/getting-started/introduction` | | `MDX_BASEURL` | Base URL for inlining relative images, or a path (e.g. `/react-three-fiber`) for root-relative ones | `http://localhost:60141`or `https://github.com/pmndrs/react-three-fiber/raw/master/docs` | | `SOURCECODE_BASEURL` | Base URL for `sourcecode:` code path, and for relative links to repository files out of `MDX`: the tree of the repository root (as the reusable workflow sets it) | `https://github.com/pmndrs/react-three-fiber/tree/main` | | `EDIT_BASEURL` | Base URL for displaying "Edit this page" URLs | `https://github.com/pmndrs/react-three-fiber/edit/master/docs` | | `NEXT_PUBLIC_URL` | Final URL of the published website | `https://pmndrs.github.io/react-three-fiber` | | `ICON` | Emoji or image to use as (fav)icon (path local to `MDX`) NB: also published at `/icon.svg`, which the libraries menu of the other pmndrs docs sites shows | `🇨🇭` or `/icon.png` or `/favicon.ico` | | `LOGO` | Logo src/path (either FQURL or local to `MDX` path) | `/logo.png` or `https://worldvectorlogo.com/r3f.png` | | `GITHUB` | Github URL (its star count shows next to the header link) | `https://github.com/pmndrs/react-three-fiber` | | `DISCORD` | Discord URL | `https://discord.com/channels/740090768164651008/740093168770613279` | | `SPONSOR_CARD` | "Sponsor Poimandres" card under the table of contents, on unless `false` -- for a site that is not a pmndrs library | `false` | | `LIBS_MENU` | Menu of the pmndrs libraries behind the site name in the header, on unless `false`: the name is then a plain link home | `false` | | `THEME_PRIMARY` | Primary accent color (unset: the pmndrs lime `#CAF543`) | `#323e48` | | `THEME_SCHEME` | Theme scheme, moot while color match is on (see `THEME_COLOR_MATCH`) | `content` or `expressive` or `fidelity` or `monochrome` or `neutral` or `tonalSpot` or `vibrant` | | `THEME_CONTRAST` | Theme contrast -- value between -1 and 1 | `0` or `-1` or `1` or `-.6` | | `THEME_NOTE` | "note" color | `#1f6feb` | | `THEME_TIP` | "tip" color | `#238636` | | `THEME_IMPORTANT` | "important" color | `#8957e5` | | `THEME_WARNING` | "warning" color | `#d29922` | | `THEME_CAUTION` | "caution" color | `#da3633` | | `THEME_CUSTOM_COLORS` | Custom colors of the theme, `name:hex[:blend]` comma-separated -- each a role, ``, `:blend` harmonizing it with the primary | `brand:#ff2d95:blend,status:#17b26a` | | `THEME_COLOR_MATCH` | Each core and custom color rendered true to its own input (Material Theme Builder's "Color match"), on unless `false`: it takes precedence over `THEME_SCHEME`, readers can toggle it from the sidebar, and the scheme toggle is hidden while color match is on | `true` or `false` | | `THEME_SECONDARY` | Secondary color, instead of the one derived from the primary | `#B03A3A` | | `THEME_TERTIARY` | Tertiary color, instead of the one derived from the primary | `#7D5260` | | `THEME_NEUTRAL` | Neutral color (the surfaces), instead of the pmndrs warm grey `#c1b793` | `#c1b793` | | `THEME_NEUTRAL_VARIANT` | Neutral variant color (the tinted surfaces, outlines), instead of the pmndrs `#495720` | `#495720` | | `THEME_ERROR` | Error color, instead of the pmndrs red `#FF4980` | `#FF4980` | | `THEME_STORYBOOK` | "storybook" color | `#ff4785` | | `THEME_NPM` | "npm" color | `#cb3837` | | `THEME_CHROMATIC` | "chromatic" color | `#fc521f` | | `CONTRIBUTORS_PAT` | GitHub token for contributors API and the header star count (see: ) | `ghp_1234567890` | | `LIB_VERSION` | Version label in the sidebar footer (default: `git describe --tags`) | `v1.2.3` | | `TAG_MATCH` | Tags the version label is read from (`git describe --match`) | `v*.*.*` | | `VERSION_URL_TEMPLATE` | URL of a branch deployment; enables the [version switcher](#version-switcher) | `https://mylib-git-{branch:vercel}-myteam.vercel.app` | | `VERSION_PRODUCTION_BRANCH` | Production branch (default: `main`) | `master` | | `VERSION_PRODUCTION_URL` | Production branch URL (default: `NEXT_PUBLIC_URL`) | `https://docs.pmnd.rs` | | `VERSION_BRANCHES` | Regex of the branches the switcher offers | `^(main\|next\|v\d+)$` | | `VERSION_BRANCHES_LIST` | Branches the switcher offers, instead of the remote's | `main,next,v9` | \* Required Readers can re-seed `THEME_PRIMARY`, `THEME_SCHEME`, `THEME_CONTRAST` and `THEME_COLOR_MATCH` from the theme controls in the sidebar. An overridden control is outlined, and a double-click (or Delete) brings the site's value back. `MDX_BASEURL` Given a `advanced/introduction.mdx` file in the `MDX` folder: ```md title="advanced/introduction.mdx" ![](dog.png) ``` becomes (for a `MDX_BASEURL=http://localhost:60141` value): ```md ![](http://localhost:60141/advanced/dog.png) ``` `http://localhost:60141` being the `MDX` folder served. > \[!TIP] When deployed on GitHub Pages, `MDX_BASEURL` will typically value something like `https://github.com/pmndrs/uikit/raw/main/docs`, thanks to [`build.yml`](https://github.com/pmndrs/docs/tree/dependabot/github_actions/pnpm/action-setup-6/.github/workflows/build.yml) rule. `MDX_BASEURL` can also be a path only, root-relative, such as `/react-three-fiber` (or `/` for a site served at the root of its domain): the `MDX` folder then has to be served at that path, on the same host as the website. URLs then come out root-relative too: ```md ![](/react-three-fiber/advanced/dog.png) ``` so they follow the website onto any host it answers on (e.g. both the deployment and the branch URL of a Vercel preview), where an absolute URL would point to one host only. > \[!NOTE] With a path, the `image` frontmatter (`og:image`) is made absolute against the origin of `NEXT_PUBLIC_URL`, when set, since social images need an absolute URL. `THEME_*` We implement [m3 design system](https://m3.material.io/styles/color/system/overview), using [material-theme-builder](https://github.com/abernier/material-theme-builder). [material-theme-builder color scheme](https://main--695eb517cb602e59b4cc045c.chromatic.com/iframe.html?id=mtb--st-1\&viewMode=story) This is an embed iframe of [material-theme-builder's `` story](https://main--695eb517cb602e59b4cc045c.chromatic.com/?path=/story/mtb--st-1). > \[!NOTE] > > - [Material Color](https://www.youtube.com/playlist?list=PLsoLz-E4Os4WWkrvRuQ7BJuVF-WfOyfWT) for more information > - The defaults are [pmndrs/design-system](https://github.com/pmndrs/design-system)'s palette: the lime `#CAF543` under color match, a warm grey neutral, and seven colors every site gets as custom colors, `lime`, `teal`, `cyan`, `purple`, `red`, `orange` and `yellow` (``). > - `THEME_PRIMARY` is the seed: the secondary and tertiary colors are derived from it, unless the site gives its own (`THEME_SECONDARY`, `THEME_TERTIARY`). The neutral, neutral variant and error colors are the pmndrs ones, unless the site gives its own (`THEME_NEUTRAL`, `THEME_NEUTRAL_VARIANT`, `THEME_ERROR`). > - `THEME_COLOR_MATCH` (on unless `"false"`) is [Material Theme Builder](https://material-foundation.github.io/material-theme-builder/)'s "Color match - Stay true to my color inputs": each core and custom color keeps its input's chroma instead of being toned down to the scheme's, so `THEME_SCHEME` is ignored and the scheme toggle is hidden while color match is on. Readers can toggle color match from the sidebar. A custom color with `:blend` is still harmonized first. `VERSION_*`, `LIB_VERSION`, `TAG_MATCH` - Label: `git describe --tags` (eg. `v10.7.9`, `v10.7.9-3-ga1b2c3d`), or `@` without tags. `LIB_VERSION` overrides it. - `TAG_MATCH` narrows the tags: | repo tags | `TAG_MATCH` | | -------------------------- | ----------- | | `v10.7.9`, `v10` | `v*.*.*` | | `leva@0.10.1`, `other@1.0` | `leva@*` | - `VERSION_URL_TEMPLATE` enables the switcher: the label lists the branches, each leading to the same page on its deployment. Full public URL (base path included), with a placeholder: | placeholder | `feat/Dark_mode` becomes | for | example | | ----------------- | ------------------------ | ---------------------- | ----------------------------------------------------- | | `{branch}` | `feat-dark-mode` | URLs you create | `https://docs-git-{branch}-pmndrs.vercel.app` | | `{branch:vercel}` | `feat-darkmode` | Vercel Git integration | `https://mylib-git-{branch:vercel}-myteam.vercel.app` | | `{branch:raw}` | `feat%2FDark_mode` | a path or query string | `https://example.com/preview?branch={branch:raw}` | - A hostname label holds 63 characters at most. When a long branch would overflow it, `{branch:vercel}` follows Vercel's own truncation, and `{branch}` keeps its slug's first `63 - (rest of the label) - 7` characters, drops a trailing `-`, and appends `-` and the first 6 hex characters of the branch name's SHA-256 (`printf %s "$branch" | sha256sum | cut -c1-6`): eg. `claude/pages-shadcn-tailwind-prep-98d23c` in `https://design-system-git-{branch}-pmndrs.vercel.app` becomes `design-system-git-claude-pages-shadcn-tailwind-pr-2675d4-pmndrs`. Outside the hostname, `{branch}` is never cut. To alias a deployment there, `pmndrs-docs version-url` prints the URL (`--hostname`: the hostname alone), or see the reusable workflow's [`version_hostname` output](/github-actions/introduction#version-switcher). - `VERSION_PRODUCTION_BRANCH` leads to `VERSION_PRODUCTION_URL`; every other branch shows a banner linking to production. - Branches: the remote's, minus `dependabot/`, `renovate/`, `changeset-release/`. `VERSION_BRANCHES` replaces that filter, `VERSION_BRANCHES_LIST` the whole list. Read at build time. > \[!IMPORTANT] > > - The per-branch URLs are yours to create: Vercel's Git integration does, `vercel deploy` does not (`vercel alias set`, see [`ci.yml`](https://github.com/pmndrs/docs/blob/main/.github/workflows/ci.yml)). > - Git needs full history and tags (`fetch-depth: 0`). ## Usage ### dev Run [`dev.sh`](https://github.com/pmndrs/docs/blob/main/dev.sh). The site listens on `PORT` (default `3000`), the MDX folder on any free port, so several checkouts can run side by side: ```sh $ ./dev.sh ``` which is: ```sh title="dev.sh" collapsible #!/bin/sh trap 'kill -9 0' SIGINT export PORT=${PORT:-3000} export _PORT=$(node -e 'const s = require("net").createServer().listen(0, () => { console.log(String(s.address().port)); s.close() })') export MDX=docs export NEXT_PUBLIC_LIBNAME="docs" export NEXT_PUBLIC_LIBNAME_SHORT="docs" export BASE_PATH= export HOME_REDIRECT= export MDX_BASEURL=http://localhost:$_PORT export SOURCECODE_BASEURL="vscode://file$(pwd)" export EDIT_BASEURL="vscode://file$(pwd)/docs" export NEXT_PUBLIC_URL= export ICON= export LOGO=gutenberg.jpg export GITHUB=https://github.com/pmndrs/docs export DISCORD=https://discord.com/channels/740090768164651008/1264328004172255393 export CONTRIBUTORS_PAT= npx serve $MDX -p $_PORT --no-port-switching --no-clipboard & pnpm run dev & wait ``` Then go to: When running the engine against another repository, set both `MDX` and `DOCS_CONFIG`; the configuration is discovered from the working directory, not the MDX folder: ```sh MDX=/path/to/library/docs DOCS_CONFIG=/path/to/library/docs.config.ts pnpm dev ``` > \[!TIP] If `HOME_REDIRECT=` empty, `/` will not redirect, and instead displays an index of libraries. ### build Run [`start.sh`](https://github.com/pmndrs/docs/blob/main/start.sh), same ports: ```sh $ ./start.sh ``` which is: ```sh title="start.sh" collapsible #!/bin/sh trap 'kill -9 0' SIGINT rm -rf out export PORT=${PORT:-3000} export _PORT=$(node -e 'const s = require("net").createServer().listen(0, () => { console.log(String(s.address().port)); s.close() })') export MDX=docs export NEXT_PUBLIC_LIBNAME="docs" export NEXT_PUBLIC_LIBNAME_SHORT="docs" export BASE_PATH= export HOME_REDIRECT= export MDX_BASEURL=http://localhost:$_PORT export SOURCECODE_BASEURL= export EDIT_BASEURL= export NEXT_PUBLIC_URL= export ICON= export LOGO=gutenberg.jpg export GITHUB=https://github.com/pmndrs/docs export DISCORD=https://discord.com/channels/740090768164651008/1264328004172255393 export CONTRIBUTORS_PAT= # The static export is the CLI's, built from this checkout: the same one the package publishes pnpm run build:cli || exit 1 node bin/pmndrs-docs.mjs build $MDX out --format website || exit 1 npx serve $MDX -p $_PORT --no-port-switching --no-clipboard & npx serve out -p $PORT & wait ``` ### CLI The published CLI builds without cloning the engine. If your custom components import packages, install those dependencies in your repository first: ```sh $ cd ~/code/pmndrs/react-three-fiber $ curl -sL https://raw.githubusercontent.com/pmndrs/docs/refs/heads/main/preview.sh | \ MDX="docs" \ NEXT_PUBLIC_LIBNAME="React Three Fiber" \ HOME_REDIRECT="/getting-started/introduction" \ ICON="🇨🇭" \ sh ``` which is: ```sh title="preview.sh" collapsible #!/bin/sh main() { trap 'kill -9 0' SIGINT export PORT="${PORT:-3000}" export _PORT="${_PORT:-$(node -e 'const s = require("net").createServer().listen(0, () => { console.log(String(s.address().port)); s.close() })')}" export VERSION="${VERSION:-latest}" export MDX="${MDX:-docs}" export NEXT_PUBLIC_LIBNAME="${NEXT_PUBLIC_LIBNAME:-docs}" # Relative assets resolve against the MDX folder, served below on the same port export MDX_BASEURL="${MDX_BASEURL:-http://localhost:$_PORT}" rm -rf "$MDX/out" # Every other option is read straight from the environment — same process, nothing to forward npx -y "@pmndrs/docs@$VERSION" build "$MDX" "$MDX/out" --format website || exit 1 npx serve $MDX -p $_PORT --no-port-switching --no-clipboard & npx -y serve "$MDX/out" -p $PORT & wait } main ``` Any [configuration](#configuration) variable goes in the same way; `VERSION` picks a published version of the CLI. Then go to: `npx @pmndrs/docs@latest build --help` lists the CLI flags, including `--config` for a configuration outside the repository root. Both `--format website` and `--format fragment` use the same Next.js build and static export. Fragments contain only the compiled document: no layout, stylesheet or script. The CLI copies assets alongside folder fragments and preserves static Mermaid and Sandpack content. ```sh $ npx @pmndrs/docs@latest build page.mdx $ cat page.mdx | npx @pmndrs/docs@latest build ``` A single file or stdin writes HTML to stdout and build logs to stderr. These inputs also run a full Next.js build. Consumer components and data use the same `docs.config.ts` as the website. ### read The same CLI reads every pmndrs library in the terminal: ```sh $ npx @pmndrs/docs # every library, every page $ npx @pmndrs/docs drei # one library $ npx @pmndrs/docs drei/performances/instances # one page $ npx @pmndrs/docs search instanced mesh # one result per line, on stdout ``` `↑↓` moves in the focused pane, `⇥` switches pane, `←→` changes library, `/` searches, `o` opens the page in a browser, `q` quits. `npx @pmndrs/docs browse --help` lists every key. `search` prints `{lib} {path} - {title}` and exits 1 when nothing matches; `--in drei` narrows it to one library, `--in drei/performances/instances` to the matching lines of one page. Pages come from each library's `llms-full.txt`, cached for an hour (`--refresh` refetches). Piped, a page goes to stdout: `npx @pmndrs/docs drei/performances/instances | glow`. ## Agents `llms.txt` dumps and the pmndrs MCP server moved to their own page: [Agents](/agents/introduction). ]]> \[!TIP] > > `title` and `description` support markdown: > > ```yaml > --- > title: "`Intro` component" > description: Introduction component for **documentation** pages with `code` and [links](#test) > --- > ``` > > ⚠️ If starting with backtick, eg ``title: "`Intro` component"`` wrap in quotes! ## MARKDOWN Worth mentioning, you can use **standard HTML**, with [tailwind](https://tailwindcss.com) support: ```md