Docs
Add Preview Dog to your site
Preview Dog is an embeddable React bar for non-production builds. Reviewers point at what's wrong and leave a note; it opens a clean, well-formed GitHub issue. The bar holds no secrets — it POSTs the note to your own route, which talks to GitHub.
Install
React 18+ is a peer dependency.
npm install @creo-team/preview-dogAdd the bar (client)
Drop <DogBar /> in once, near the root. Gate it to non-production with the enabled prop — when false it renders nothing.
import { DogBar } from "@creo-team/preview-dog";
export function Bar() {
// Render it only on non-production builds — the bar collapses to
// nothing when `enabled` is false (no DOM, no listeners).
return (
<DogBar
repo="acme/website"
enabled={process.env.NODE_ENV !== "production"}
// Pass the build commit so reviewers can approve this preview.
build={{ commit: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA }}
/>
);
}Add the route (server)
createDogBarHandler is a web-standard handler (Request → Response) — it runs on Node or the edge. It holds the GitHub token; the client never sees it.
// app/api/dogbar/route.ts
import { createDogBarHandler } from "@creo-team/preview-dog/server";
const handler = createDogBarHandler({
repo: process.env.PREVIEW_DOG_REPO!, // "owner/name"
githubToken: process.env.PREVIEW_DOG_GITHUB_TOKEN!, // issues: read & write
openRouterKey: process.env.OPENROUTER_API_KEY, // optional → AI-tidied issues
passphrase: process.env.PREVIEW_DOG_PASSPHRASE, // gate for commenting + approvals
sessionSecret: process.env.PREVIEW_DOG_SESSION_SECRET, // HMAC key for the session cookie
siteContext: "ACME storefront — checkout is the money path.", // optional: tunes Ask
});
export const GET = handler;
export const POST = handler;- PREVIEW_DOG_REPOrequired
- "owner/name" the issues open in
- PREVIEW_DOG_GITHUB_TOKENrequired
- token with issues read & write
- OPENROUTER_API_KEYoptional
- enables AI-tidied issues + Ask
- PREVIEW_DOG_PASSPHRASEoptional
- gate for posting comments + approvals
- PREVIEW_DOG_SESSION_SECREToptional
- HMAC key for the session cookie
Pre-fill reviewer identity (optional)
If your app already knows who the reviewer is, set these cookies and the bar pre-fills the name/email fields — they only confirm the passphrase. Prefill only; the signed-session gate is unchanged.
// In your own auth/middleware, after you know who the reviewer is:
document.cookie = "PREVIEW_DOG_NAME=Ada Lovelace; Path=/";
document.cookie = "PREVIEW_DOG_EMAIL=ada@acme.dev; Path=/";
// → the bar pre-fills name/email; the reviewer only confirms the passphrase.
// On a trusted preview you can also skip the prompt entirely — pass the
// passphrase too (cookie or the <DogBar reviewer={...} /> prop) and the bar
// signs the reviewer in silently. It's a mild secret, so only on trusted hosts.
document.cookie = "PREVIEW_DOG_PASSPHRASE=your-preview-pass; Path=/";Approvals
Pass build={{ commit }} and a signed-in reviewer can approve the preview from the bar — it turns a green check. Approvals are recorded as comments on a hidden GitHub tracking issue, keyed by commit, so they never clutter your real issue list.
<DogBar repo="acme/website" enabled={!isProd}
build={{ commit: gitSha, branch: gitBranch }} />Theming
The bar is self-contained (inline styles, no CSS framework). Match your brand with a few props.
<DogBar
repo="acme/website"
enabled={!isProd}
theme="dark" // "light" | "dark"; omit to follow the device
accent="#0e8a6e" // brand accent
label="Staging" // short environment label in the pill
/>;Custom tabs & the tour
Add your own pill + panel with a render(ctx) — the bar wraps it in native chrome and hands you the accent, theme, reviewer, and a close(). A first-visit guided tour points out the features and replays from the ? button.
import { DogBar, type DogTab } from "@creo-team/preview-dog";
// Each tab adds a pill + a panel. `render(ctx)` returns just the body —
// the bar supplies the chrome, theming, and `ctx.close()`.
const tabs: DogTab[] = [
{
id: "changelog", // stable id; avoid the reserved internal ids
label: "Changelog",
hint: "What shipped in this build",
badge: 3, // optional count on the pill
render: ({ accent, theme, reviewer, close }) => (
<Changelog accent={accent} onDone={close} />
),
},
];
// A first-visit tour auto-opens once and replays from the ? button.
// Opt out with tour={false}.
<DogBar tabs={tabs} />;Try it with no backend
Pass a demo adapter to drive the full Issues/Ask workspace from in-memory data — handy for local dev and Storybook.
import { DogBar, createDemoAdapter } from "@creo-team/preview-dog/client";
// No GitHub config needed — drives the whole workspace from in-memory data.
<DogBar adapter={createDemoAdapter()} />;