Skip to content

[NO-TICKET] Stamp development builds as a sandbox, so builder previews show the widget - #463

Closed
mariojgt wants to merge 1 commit into
mainfrom
mariot/dev-sandbox-stamp
Closed

mariojgt wants to merge 1 commit into
mainfrom
mariot/dev-sandbox-stamp

Conversation

@mariojgt

@mariojgt mariojgt commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

No ticket.

What changed

The Patchstack block that setup and scan write into a JSX root layout (or an Astro layout) now covers every kind of build, not just production:

  • Production build: sets the production marker, exactly as before (window.__PATCHSTACK_PROD__ / window.__PATCHSTACK_BUILD__).
  • Any other build (a dev server, a builder's preview): sets window.__PATCHSTACK_ENV__="sandbox". The widget already reads that stamp as "this is a preview".

So the widget now shows its owner panel in a builder's preview even when that preview runs on a host the widget does not know.

Why

The widget still did not show in v0's in-chat preview, even after vusercontent.net went on the preview lists (widget #190, SaaS #2355). v0 now runs chat previews somewhere else, and that host could change again. A list of hosts has to chase every builder.

The page could already say it is a preview: the widget checks for window.__PATCHSTACK_ENV__ === "sandbox", and mark-build writes that stamp into a sandbox build's HTML. But a dev server never runs mark-build, and the block in the layout said nothing outside production ({gate && (…)}). On an unknown host, with no marker and no stamp, the widget had no reason to show anything.

Fix

  • buildSourceMarkerSnippet in src/mark-build.ts now returns {gate ? (<production marker>) : (<sandbox stamp>)}. The gate is the same framework expression as before (process.env.NODE_ENV === 'production', import.meta.env.PROD, !import.meta.dev), so a production build gets the same marker it always did.
  • The block is managed: scan removes it and writes it again every time. Existing apps get the new shape on their next install or build (the postinstall and prebuild hooks both run scan) once they update @patchstack/connect.
  • AGENT-INSTALL.md: the paragraph about the production marker said the block was "inert in dev and preview builds". It now says what the block does in those builds.

What this does not change

The block only differs in builds that are not production builds. Everything that works today keeps the answer it has now:

  • Published sites are production builds, so they get the same production marker as before. The live Hostinger and Lovable test sites both serve it today.
  • Known builder previews (Lovable's id-preview--…lovable.app and lovableproject.com, Hostinger's app-preview.com and ai-builder.hostinger.com, localhost) are recognised by host. The widget checks that before it looks at the stamp.
  • Published-site domains (hostingersite.com, replit.app, bolt.host), the production marker, and the server's own "live" answer for the site's registered address are also checked before the stamp.
  • Plain HTML shells don't use this block, so they are untouched.
  • Nothing else reads the stamp. Only the widget reads it; nothing in Connect or the SaaS does.

One case does change. A live site that runs a dev server (not a production build), on a custom domain that isn't the site's registered address. Today the widget hides there. With this, it shows its launcher, closed: a stamp on its own never opens the owner's panel. That is the outcome the widget's design record already accepts for a wrongly stamped live site, and data-build-mode="false" on the widget tag turns the owner's panel off on that page.

Verified

  • The real v0 project's app/layout.tsx (shared by the owner; it already had the old block):
    • the old block is replaced, leaving one;
    • the file parses as TSX with no errors;
    • a second run changes nothing.
  • tests/mark-build.test.ts:
    • new test: for every supported framework, the non-production branch sets the sandbox stamp and never the production marker or build ID;
    • the Astro test and the "marker above the widget tag" test now expect the new shape.
  • tests/guide.test.ts: the printed snippet test now expects the new shape.
  • Gates: npm run typecheck, npm run build and capabilities:check are green. Full npm test: 4652 passed, 7 skipped.

Out of scope, worth a follow-up

  • Prompt wording. The install prompt asks the agent to "leave dev builds unchanged". That refers to what the agent does, and Connect writes this block itself, but an agent auditing the docs could read it as a contradiction. Watch for it in the field test below. Changing the prompt would need its own hostile run before shipping.
  • Builders that preview a production build (rather than a dev server) still need their host on the preview list, as before. v0 previews on a dev server (its sandbox loads the development JSX runtime), so this covers it.

Docs: AGENT-INSTALL.md updated (the production marker paragraph). Agents read the shipped docs, so the hostile field test is owed after the release that carries this, plus standard/lovable for doc accuracy.

🤖 Generated with Claude Code

…idget

The managed marker block in a JSX root shell or Astro layout now has two
branches. A production build still sets the production marker. Any other
build sets window.__PATCHSTACK_ENV__="sandbox", the stamp the widget
already reads as a preview. A builder preview served from a host the
widget does not list now shows the owner's panel instead of nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mariojgt

Copy link
Copy Markdown
Contributor Author

/review

@coderbuds

coderbuds Bot commented Oct 28, 2026

Copy link
Copy Markdown

🎯 Elite quality (97%) — Converts the production-only marker into a ternary that stamps non-production builds as a sandbox, with matching tests.

📦 Small

See how your team is trending →

@mariojgt

Copy link
Copy Markdown
Contributor Author

/review

@mariojgt

Copy link
Copy Markdown
Contributor Author

Closing in favour of a narrower fix that leaves Connect's output unchanged: v0's sandbox preview host (vercel.run) is added to the preview lists in patchstack/sass-webvdp-widget#191 and patchstack/saas#2366.

@mariojgt mariojgt closed this Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants