Repository navigation
[feat] ENG-3684 - Carry the production marker to server-rendered builds - #165
Merged
Merged
Conversation
The connector has two injection paths and only one of them reaches a server-rendered deploy. The widget tag is written into source, so it ships with the app; `__PATCHSTACK_PROD__` is stamped into built HTML, and a server-rendered root never produces a static HTML file to stamp. On those stacks the marker never arrives, so the widget reads the live site as build mode and shows the claim flow to visitors. `mark-build` made this invisible: finding a build directory with no HTML in it printed "Nothing to mark" and exited 0, which is indistinguishable from success. - `guide` now asks for the marker whenever the root shell is code rather than HTML, printing the JSX snippet for React-family roots and describing the requirement for the rest, and counts it as an outstanding step. - The snippet is gated on the framework's own production expression. An ungated marker would also fire in the hosted builder's preview, which is where the owner still needs the claim flow. - The marker stays an inline document script. The widget tag is `defer`, so only a parser-executed script is ordered ahead of its init for certain. - `mark-build` now names the server-rendered case and points at `guide` instead of reporting nothing to do. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Production marker integration is well-structured with thorough test coverage. 🎯 Quality: 100% Elite · 📦 Size: Medium 📈 This month: Your 62nd PR — above team average · Averaging Excellent |
Contributor
Author
|
/review |
daniloradovic
approved these changes
Aug 24, 2026
The marker only reaches production if it is in the source shell before the build runs, and asking the developer to paste it there makes the one step that must never be forgotten the one step nobody automates. `scan` is already a pre-build hook, and it already edits the source shell to place the widget tag on plain HTML projects. It now does the same for the marker on JSX roots: insert it above the widget tag so document order puts it first, fall back to `<head>` then `<body>`, and wrap it in the same managed `#region` fence the protect installer uses so a re-run refreshes the block rather than stacking copies. A marker the developer placed by hand is adopted, not duplicated. That makes the flag arrive on its own from `bun run build` or `npm run build`, the same way the dependency scan and the widget tag already do. `guide` now points at `scan` for this and keeps the snippet as the fallback for roots where no anchor was found. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Build scripts commonly chain the scan as `patchstack-connect scan || true`, so a failed or offline post is expected to be survivable. Running the marker pass after `postManifest` made it the opposite: any network error skipped the write and the build shipped without a production flag, silently. The marker carries no site UUID and needs no round-trip, so nothing about it justified waiting on the server. It now runs as soon as the framework is known and before the post, still after the --dry-run return so a preview stays side-effect free. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes ENG-3684
What changed
The connector injects two things, by two different routes. The widget tag goes into source, so it ships with the app.
__PATCHSTACK_PROD__gets stamped into built HTML — and a server-rendered root never produces a static HTML file to stamp. On those stacks the marker never arrives, the widget reads the published site as build mode, and visitors get the claim flow instead of the report form.mark-buildhid it. Finding a build directory with no HTML in it printedNothing to markand exited 0, which looks exactly like success.guidenow asks for the marker whenever the root shell is code rather than HTML. React-family roots get a literal JSX snippet; the rest get the requirement described, because their head mechanism (useHead,<svelte:head>, Astro frontmatter) is not a plain script tag and a wrong snippet costs more than an accurate sentence.import.meta.env.PRODwhere the bundler defines it,process.env.NODE_ENVfor Next/Gatsby,!import.meta.devfor Nuxt. The gate is load-bearing: an ungated marker also fires in the hosted builder's preview, which is where the owner still needs the claim flow.defer, so only a parser-executed inline script is ordered ahead of its init for certain.mark-buildnow names the server-rendered case and points atguide.Verification
npm test— 1307 passed, 6 skipped, 106 files.npm run typecheckclean.Smoke-tested against a fixture mirroring the reported site (TanStack Start, widget tag already in
__root.tsx), which reproduces its exact state:Before merging
This changes
src/guide.tschecklist output, so perCLAUDE.mdit needsnode field-test/run.mjs --persona hostile --rounds 3. I have not run it — it needs a real agent and 30–50k tokens per round.Worth a reviewer's opinion: this asks the developer to paste a snippet. The alternative is having the installed server middleware inject the marker into SSR responses, which is automatic but only covers deployments where
protectis wired. I went with the snippet because it matches how the widget tag already gets placed on these stacks and has no runtime dependency.🤖 Generated with Claude Code