You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(web): streamed device toolbar starts at the panel size - #35664
PreviewView's handleToggleDeviceToolbar sized the first freeform viewport from the browser surface store's rect, which only BrowserSurfaceSlot (local desktop rendering) publishes. Streamed server tabs mount ServerBrowserSurface, which never writes that rect, so browserResponsiveViewportForToggle got null and fell back to 1024x768. The fix adds a ref to the wrapper div around ServerBrowserSurface. For streamed tabs (isServerTab) the toggle passes that wrapper's getBoundingClientRect() as panelRect. The toggle only uses this size when switching from fill mode, and in fill mode the wrapper is the same box ServerBrowserSurface measures and reports to the server, so the first fixed viewport matches the panel. Local desktop tabs and natively rendered server tabs still use the store rect. 6 lines in one file. No new regex or parser.
Commit b63d3c5 (origin/main). Started T3CODE_DEV_SEED=0 vp run dev in a fresh worktree and paired the web client in a 1280x800 browser tab. Added a scratch git project and started a Replay thread, then opened the right panel and added a Browser surface. In the plain web client this is a server-streamed tab: it shows 'You have control' and draws on a canvas. Served a local page that prints its own innerWidth x innerHeight and opened it from the local servers list. In fill mode the page reported 'viewport 539x675', matching the 539px-wide panel. Opened the Preview menu and clicked 'Show device toolbar'. The toolbar appeared as Responsive 1024 x 768, and the streamed page re-rendered reporting 'viewport 1024x768', scaled down inside the 539px panel. Failing test: PreviewView.browser.test.tsx 'sizes the first device viewport of a streamed tab to its panel' renders a runtime:'server' tab that is not natively rendered and clicks Preview menu → Show device toolbar. It expects commitBrowserViewportChange to receive freeform resolveResponsiveBrowserViewportSize(server surface rect, 1) = 394x240, but on main it receives 1024x768.
Evidence
In Chromium at 1280×800 with light theme and fresh unseeded app state, create a scratch project and Replay thread; open the right panel → Browser; navigate to the local viewport-reporting page; open Preview menu → Show device toolbar; click Refresh on both sides without editing dimensions.
The scenario runner's proof.json reports failsOnBase=true and passesOnHead=true. Refresh replaced a stale streamed frame on both sides; dimensions were never entered manually.
AI-assisted; verified with the tests and tools listed above.
Not shown:
Immediate canvas repaint without Refresh: the stream retained its previous frame; both final captures include the same Refresh action, with dimensions untouched.
Tests
vp test run apps/web/src/components/preview/PreviewView.browser.test.tsx: 10/10 pass with the fix; with the fix stashed, the repro test 'sizes the first device viewport of a streamed tab to its panel' fails with width 1024. vp run check:changed: format, lint, knip, typecheck (2 packages), tests and react compiler all pass.
Not in this change
ServerBrowserSurface could publish its rect to browserSurfaceStore so every consumer sees it; that is a larger change than this bug needs.
AI-assisted; verified with the tests and tools listed above.
Reproduces #35648: on a server-streamed preview tab, Show device toolbar
commits 1024x768 because no BrowserSurfaceSlot publishes the panel rect.
AI-assisted; verified with the tests and tools listed above.
ServerBrowserSurface never publishes a rect to the browser surface store,
so turning on the device toolbar for a streamed tab fell back to 1024x768.
Measure the streamed surface's own box instead.
AI-assisted; verified with the tests and tools listed above.
Macroscope's review found this PR approvable — Streamed previews now use the panel’s measured dimensions when enabling the device toolbar instead of unnecessarily falling back to 1024×768. The change is limited to that sizing action and preserves configured viewport preferences and other rendering paths.
No code changes detected at 7a14c35. Prior analysis still applies.
You can add or adjust custom eligibility rules. Learn more.
Reviewing files that changed from the base of the PR and between 0b8e794 and 7a14c35.
You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.
Use the checkbox below for a quick retry:
Trigger review
No actionable comments were generated in the recent review.
Walkthrough
When a server-rendered tab switches from fill viewport to responsive viewport, PreviewView now derives the initial viewport dimensions from the server surface container. A browser test checks this behavior for a streamed tab.
Changes: Streamed preview viewport sizing
Layer / File(s)
Summary
Use server surface dimensions for responsive viewports apps/web/src/components/preview/PreviewView.tsx, apps/web/src/components/preview/PreviewView.browser.test.tsx
PreviewView uses the server surface container bounds for server-rendered tabs and retains the browser surface store rect for other tabs. The test verifies that a streamed tab receives a freeform viewport sized from the server surface panel dimensions.
Opening the device toolbar on a streamed tab should now start at the panel size instead of 1024×768. No merge-blocking risk was identified, and a browser test covers the new behavior.
Pre-merge checks: 4
Check name
Status
Explanation
Title check
The title follows the conventional commit format and names the main change: the streamed device toolbar's first viewport now starts at the panel size instead of the 1024x768 fallback. It matches the l…
Linked Issues check
Issue #35648 requires that the first fixed viewport on a streamed server tab use the preview panel size, not the 1024x768 fallback. The reviewed diff in PreviewView.tsx adds serverSurfaceBoxRef to the…
Out of Scope Changes check
The whole-PR diff against the merge base b63d3c5 changes one hunk set in apps/web/src/components/preview/PreviewView.tsx: a new ref declaration, a ref attachment on the existing wrapper div, and the i…
Description check
The description covers the problem, the change, scope with a linked issue, and verification. It explains the root cause (the browser surface store rect is not published for streamed server tabs, so th…
Full details: Title check
Explanation
The title follows the conventional commit format and names the main change: the streamed device toolbar's first viewport now starts at the panel size instead of the 1024x768 fallback. It matches the linked issue and the code change in PreviewView.tsx.
Full details: Linked Issues check
Explanation
Issue #35648 requires that the first fixed viewport on a streamed server tab use the preview panel size, not the 1024x768 fallback. The reviewed diff in PreviewView.tsx adds serverSurfaceBoxRef to the wrapper div around ServerBrowserSurface. When isServerTab is true, the toggle passes that wrapper's getBoundingClientRect() as panelRect to browserResponsiveViewportForToggle. Local and natively rendered tabs keep the store rect. This covers the null-rect path described in the issue. The PR description reports that the repro test 'sizes the first device viewport of a streamed tab to its panel' fails on the base with width 1024 and passes with the fix. I did not rerun the tests. The description also states that the wrapper is the box ServerBrowserSurface measures. The evidence does not include a running-client check of the rendered page. That check is not a coding requirement of the issue.
Full details: Out of Scope Changes check
Explanation
The whole-PR diff against the merge base b63d3c5 changes one hunk set in apps/web/src/components/preview/PreviewView.tsx: a new ref declaration, a ref attachment on the existing wrapper div, and the isServerTab conditional for panelRect in the device-toolbar toggle. Each change serves the streamed-tab toolbar sizing objective of #35648. The test file change, per the change summary, adds the streamed-tab regression test that supports this objective. No unrelated change was found. The PR description also states that the store rect path is unchanged for local and natively rendered tabs.
Full details: Description check
Explanation
The description covers the problem, the change, scope with a linked issue, and verification. It explains the root cause (the browser surface store rect is not published for streamed server tabs, so the 1024x768 fallback applies). It names the changed file and the affected behavior. Verification includes a test name, before/after results, and commands run. Before/after screenshots and recordings are linked. The template's Problem, Change, Scope, and Verification sections are all filled in, and the model and harness are named.
Finishing Touches
Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Resolved by hand in PreviewView.browser.test.tsx, keeping both sides: main's tab-1 runtime line (nativeServerTab or streamedServerTab, from pingdotgg#35664) and this branch's loadFailed navStatus.
github-actionsBot
added a commit
to omarcresp/t3code-flake
that referenced
this pull request
Nov 13, 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
size:XS0-9 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.
1 participant
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.
PreviewView's handleToggleDeviceToolbar sized the first freeform viewport from the browser surface store's rect, which only BrowserSurfaceSlot (local desktop rendering) publishes. Streamed server tabs mount ServerBrowserSurface, which never writes that rect, so browserResponsiveViewportForToggle got null and fell back to 1024x768. The fix adds a ref to the wrapper div around ServerBrowserSurface. For streamed tabs (isServerTab) the toggle passes that wrapper's getBoundingClientRect() as panelRect. The toggle only uses this size when switching from fill mode, and in fill mode the wrapper is the same box ServerBrowserSurface measures and reports to the server, so the first fixed viewport matches the panel. Local desktop tabs and natively rendered server tabs still use the store rect. 6 lines in one file. No new regex or parser.
Fixes #35648
Reproduction on main
Commit b63d3c5 (origin/main). Started
T3CODE_DEV_SEED=0 vp run devin a fresh worktree and paired the web client in a 1280x800 browser tab. Added a scratch git project and started a Replay thread, then opened the right panel and added a Browser surface. In the plain web client this is a server-streamed tab: it shows 'You have control' and draws on a canvas. Served a local page that prints its own innerWidth x innerHeight and opened it from the local servers list. In fill mode the page reported 'viewport 539x675', matching the 539px-wide panel. Opened the Preview menu and clicked 'Show device toolbar'. The toolbar appeared as Responsive 1024 x 768, and the streamed page re-rendered reporting 'viewport 1024x768', scaled down inside the 539px panel. Failing test: PreviewView.browser.test.tsx 'sizes the first device viewport of a streamed tab to its panel' renders a runtime:'server' tab that is not natively rendered and clicks Preview menu → Show device toolbar. It expects commitBrowserViewportChange to receive freeform resolveResponsiveBrowserViewportSize(server surface rect, 1) = 394x240, but on main it receives 1024x768.Evidence
In Chromium at 1280×800 with light theme and fresh unseeded app state, create a scratch project and Replay thread; open the right panel → Browser; navigate to the local viewport-reporting page; open Preview menu → Show device toolbar; click Refresh on both sides without editing dimensions.
Before recording · After recording
Scenario source
The scenario runner's proof.json reports failsOnBase=true and passesOnHead=true. Refresh replaced a stale streamed frame on both sides; dimensions were never entered manually.
AI-assisted; verified with the tests and tools listed above.
Not shown:
Tests
vp test run apps/web/src/components/preview/PreviewView.browser.test.tsx: 10/10 pass with the fix; with the fix stashed, the repro test 'sizes the first device viewport of a streamed tab to its panel' fails with width 1024. vp run check:changed: format, lint, knip, typecheck (2 packages), tests and react compiler all pass.
Not in this change
AI-assisted; verified with the tests and tools listed above.