04 — Creator Onboarding
The wizard flow that takes a brand-new creator from "I opened BKA for the first time" to "my published post is live on my own infrastructure." Designed to be 15-30 minutes, one time, never again.
Goals
- Get the creator to first-publish as fast as possible
- Make the infrastructure setup educational, not opaque (so creators understand what they own)
- Automate every step that can be automated; surface only the steps that require the creator's own credentials
- Make rollback easy — if the wizard fails partway, the creator can retry or back out without orphaned resources
Pre-wizard: what we ask the creator to have
At the very start of the wizard, before any setup:
- A Google account (for Google SSO; the same identity is used across binary-blender apps)
- A GitHub account (free tier is fine; pro is fine too)
- A Cloudflare account (free tier covers most creators)
- (Optional) A domain name they want to use for their site. If none, they'll get
*.pages.devfor free; can add a domain later.
We do NOT ask them to install Node, learn Git, or have any technical setup beyond the three accounts above. The wizard does the rest.
The wizard, step by step
The wizard is presented as a numbered checklist. Each step has: a short explanation of WHY it's happening, a button to do the action, and a confirmation when it completes.
Step 1: Sign in with Google
Standard Google sign-in. Same flow as the rest of the binary-blender apps. The wizard explains:
"We use Google for identity across all binary-blender apps so you have one sign-in, not five. We don't store your Google data on our servers — we have no servers in your request path."
After sign-in: BKA writes the user record to the local OPFS-SQLite (cross-app shared with Foundry / Community).
Step 2: Connect your GitHub account
Opens a popup window to GitHub's OAuth authorize page (GitHub App OAuth, NOT a fine-grained PAT — better UX, fewer copy-pastes). The GitHub App requests:
- Repository creation (for the two repos)
- Repository contents read+write (for publishing)
- Releases read+write (for binary uploads)
Scoped to the user, not the whole account.
The wizard explains:
"We're going to create two GitHub repos in your account — one private (your working notes) and one public (your published archive). You can browse them on github.com any time. If you ever want to leave, your content is right there."
After auth: BKA holds the GitHub OAuth token in localStorage (treat as a secret).
Step 3: Pick your handle
Short slug for repo naming + viewer site URL. E.g., chris → repos become chris-bka-private + chris-bka-public; default site URL becomes chris-bka-public.pages.dev.
We validate the slug is available on GitHub before proceeding.
Step 4: Provision your two GitHub repos
BKA calls the GitHub API to create both repos in the creator's account:
<handle>-bka-private(private) — initialized with a README explaining the repo's role + a.gitignoretemplate<handle>-bka-public(public) — initialized with a README + a starterposts/index.json+ a starterfeed.json+ the viewer-template source as a subdirectory (so the Pages build has something to build)
This is one API call per repo. ~5 seconds total.
The wizard explains:
"Your private repo is where drafts and scratch go — nobody else sees it. Your public repo is where things go when you click Publish. You can browse both on github.com at any time."
Step 5: Connect your Cloudflare account
Opens a popup to Cloudflare's OAuth flow (if available — CF has been rolling this out) OR walks the creator through generating a scoped API token in the CF dashboard.
For the API-token path: we provide a one-click "create token with these exact permissions" link to the CF dashboard, pre-filled with the minimum scopes:
- Account: Workers & Pages — Edit
- Account: Cloudflare Pages — Edit
- (Optional) Account: R2 — Edit (if creator opted into comments/subscribers later)
- (Optional) Zone: DNS — Edit (if creator's bringing their own domain)
The creator copies the token into BKA. BKA holds it in localStorage (treat as a secret).
The wizard explains:
"Cloudflare is where your site lives. We're using your account — not ours. You'll pay Cloudflare directly (their free tier covers most creators for a long time). If you ever want to leave BKA, your site stays on your Cloudflare account regardless."
Step 6: Provision your Cloudflare Pages project
BKA calls the CF API to:
- Create a Pages project connected to the
<handle>-bka-publicGitHub repo - Set the build command (
npm run buildon the viewer-template subdirectory) - Set the output directory (
dist/) - Trigger the first build
CF Pages auto-deploys from the public repo from this point forward. ~30 seconds for the first build.
Step 7: (Optional) bind a custom domain
If the creator has a domain:
- BKA calls CF API to add the custom domain to the Pages project
- BKA shows the creator the DNS records they need to add (CNAME pointing at the Pages project)
- If the domain's DNS is already on CF, BKA can add the records directly. Otherwise: copy-pastable record values for the creator's existing registrar.
If skipped: site lives at <handle>-bka-public.pages.dev (the default Pages URL). Creator can bind a domain later.
Step 8: Register with the discovery indexer (optional, opt-in)
BKA explains:
"If you want, we can register your site's feed with the BKA discovery indexer so other people can find you when they ask BKA 'what should I see today?' This is purely opt-in — your site works without it, your audience can subscribe via RSS without it. Want in?"
If yes: BKA calls our indexer with {feedUrl, googleIdToken} to register. Creator can unregister at any time.
If no: skip. Creator's site is still public and discoverable by anyone who knows the URL.
Step 9: First publish
BKA pre-fills a starter post ("Hello, world. This is my new site on my own infrastructure.") + walks the creator through clicking Publish:
- Commits the post to the public repo
- Updates
/feed.json - Pushes
- CF Pages rebuilds
- (Optionally) BKA pings the indexer "I just published, please re-pull"
The wizard concludes:
"Your site is live at [their URL]. Bookmark it. The next time you open BKA, you'll skip straight to the composer — the wizard is done. Welcome to your own platform."
Failure handling
Each step should be idempotent. If the wizard crashes or the creator backs out, re-running starts from the right step.
State is persisted to OPFS-SQLite under a wizard_state table:
CREATE TABLE wizard_state (
handle TEXT PRIMARY KEY,
step INTEGER NOT NULL, -- highest completed step
github_token TEXT, -- (sensitive; encrypted at rest? — open question)
cf_token TEXT, -- (same)
cf_account_id TEXT,
private_repo TEXT,
public_repo TEXT,
cf_pages_project TEXT,
custom_domain TEXT,
indexer_registered INTEGER DEFAULT 0,
created_at INTEGER NOT NULL
);
The wizard reads this on open. If a row exists with step < 9, resume at the next step.
Common failure modes + recovery:
- GitHub OAuth denied → ask creator to retry; the wizard can't proceed without it
- GitHub repo already exists → ask if creator wants to use the existing one or pick a new handle
- CF token wrong scopes → show the exact missing scope, deep-link back to the CF dashboard with the right permissions pre-checked
- CF Pages project creation failed → show the CF error verbatim (selectable text per the feedback memory); offer "retry" + "skip and finish wizard, set up Pages manually" paths
- DNS records not propagating → wizard moves on (don't block on DNS); shows a "DNS pending" indicator on the dashboard later
After the wizard
Subsequent BKA opens skip the wizard entirely. The dashboard shows:
- The creator's site URL (clickable)
- A "draft new post" button
- A list of recent drafts (private repo)
- A list of recent published posts (public repo)
- (If indexer-registered) the indexer's "stats for your site" widget
The wizard is accessible via a settings menu for re-running (e.g., to bind a new domain), but the creator's expected interaction is: compose → publish → repeat.
What the wizard never does
- Never asks the creator to install software (no Node, no Git CLI, no anything beyond the browser)
- Never asks the creator to copy-paste config files (we generate everything via API)
- Never asks the creator to wait for "us" to provision something (no human-in-the-loop on our side)
- Never sends the creator's tokens to our servers (everything happens browser → GitHub/CF directly; the only writes to us are explicit indexer-registration calls with a Google JWT, never a GitHub or CF token)
- Never leaves the creator in a half-set-up state (every step is idempotent; the wizard either completes or rolls back cleanly)