Host the website and docs
Run your own copy of this site (landing page, docs and the live demo in apps/www) on Vercel or in Docker behind your reverse proxy.
The site you are reading is apps/www in the repository: a Next.js app with the landing page, these docs, the
changelog and the live demo on /demo. It needs no database — the demo keeps its sandboxes in memory and
resets them every 10 minutes. You only need this page if you want to publish your own copy, for example a fork
or an internal mirror; running Pinwren itself is covered in Deploy on your server.
Before you build, set your domain and links in
apps/www/src/lib/site.ts
(SITE_URL, the GitHub repository, the Docker image name). Canonical links, the sitemap and social cards are
built from it.
The build reads the rest of the repository: the environment variable reference comes from
packages/api/src/env.ts, the changelog from CHANGELOG.md, and the widget the demo loads from
packages/widget/dist (built automatically when it is missing). Build from a full checkout, not from the
apps/www folder alone.
- Import the repository in Vercel (Add New › Project).
- Root Directory:
apps/www. Leave Include files outside the root directory in the Build Step on — the build reads the rest of the repository. - Framework preset: Next.js. Keep the default build command (
pnpm build, which runsnode scripts/prepare.mjs && next build) and output settings. - Install command:
pnpm install --frozen-lockfile. Vercel runs it at the repository root, so the whole workspace is installed. - Environment variables:
ENABLE_EXPERIMENTAL_COREPACK=1, so Vercel uses the pnpm version pinned in the rootpackage.json(packageManager).DEMO_TRUST_PLATFORM_IP_HEADER=x-vercel-forwarded-for, so the demo's rate limits see each visitor's address instead of putting everyone in one bucket.
- Deploy, then add your domain under Settings › Domains.
The demo on Vercel
The demo API runs as Next.js route handlers, which Vercel turns into serverless functions. Two things follow: Vercel refuses request bodies over 4.5 MB, so a demo bug report with a very large screenshot fails there (the demo itself accepts up to 12 MB); and sandboxes live in one function instance's memory, so a visitor may occasionally land on an instance that doesn't have their demo feedback. Neither affects the landing page or the docs. For a demo that behaves exactly like a real server, use Docker.
Demo settings
The demo needs no configuration. These optional variables tune it:
| Variable | Default | Effect |
|---|---|---|
DEMO_RESET_MINUTES | 10 | How long a visitor's demo feedback is kept. |
DEMO_MAX_SANDBOXES | 2000 | Live sandboxes in memory; the least recently used is dropped to make room. |
DEMO_MAX_SANDBOX_BYTES | 6291456 | Bytes stored per sandbox (6 MiB). |
DEMO_MAX_TOTAL_BYTES | 201326592 | Bytes across all sandboxes (192 MiB). |
DEMO_TRUST_PLATFORM_IP_HEADER | unset | A header your platform sets itself with the visitor's address (Vercel: x-vercel-forwarded-for). |
PINWREN_TRUST_PROXY | unset | Reverse proxies in front of the site, as for the app. |