Skip to content

feat(web): open terminal dev server links without asking - #156

Merged
incognitojam merged 1 commit into
mainfrom
t3code/terminal-loopback-links
Aug 15, 2026
Merged

feat(web): open terminal dev server links without asking#156
incognitojam merged 1 commit into
mainfrom
t3code/terminal-loopback-links

Conversation

@incognitojam

Copy link
Copy Markdown
Collaborator

Note

TL;DR: Cmd-clicking an http://localhost:5173 link in the terminal now opens the integrated browser directly instead of popping a two-item chooser first. Non-loopback links are unchanged. Follow-up to #153, but independent of it.

The problem

Activating a loopback link in the terminal showed a menu at the cursor — "Open in preview" / "Open in browser" — on every single click. Activation is already a deliberate modifier gesture (cmd-click on macOS, ctrl-click elsewhere), so the chooser added a second click to every visit to a dev server you are iterating on, for a decision that is nearly always the same one.

Non-loopback URLs never showed the menu; they already went straight to the system browser. So the menu was the only place in the app where following a link asked a question first.

What changed

openTerminalLinkInPreview opens loopback links in the integrated browser and hands everything else to the system browser, with no menu in between. That deletes the menu plumbing: TerminalLinkContextMenuShowError, and the localApi and position arguments that only existed to position and show it — 107 lines out, 63 in.

The loopback test, the failure fallback, the interrupt handling, and the origin-only error logging (so a link carrying a token in its query is not logged) are all unchanged.

Reverse state

The way back out is the integrated browser's own open-in-system-browser button in PreviewChromeRow, which is one click and already there. I deliberately did not invent a modifier for "system browser instead": cmd/ctrl is already spent on activation itself, and a shift variant would be undiscoverable. If it turns out people want the choice back, a setting is the honest shape for it, not a menu on every click.

Relationship to #153

Same reasoning applied to a different surface, and the two together make the rule uniform: a loopback link opens in the integrated browser because it is the only browser that can reach the environment's ports; every other host opens in the system browser, where the reader is signed in.

They touch disjoint files and can land in either order, so this is a separate PR rather than a stacked one.

Surfaces

  • Desktop: new behavior.
  • Web in a plain browser: unchanged. isPreviewSupportedInRuntime() is false, so links fall through to the system browser exactly as before.
  • Mobile: no terminal drawer, nothing to change.

Verification

  • vp test run apps/web/src/components/preview/openTerminalLinkInPreview.test.ts
  • vp run @t3tools/web#typecheck
  • vp check on the three changed files

Checklist

  • This PR is focused on removing one chooser from one gesture
  • I explained what changed and why
  • No before/after image: the terminal link looks identical, and the visible difference is the absence of a menu. Verified manually.
  • No video is needed because this change adds no motion or timing behavior

Written by an agent (Claude Code, claude-opus-5).

Cmd-clicking a loopback link in the terminal popped a two-item menu — open
in preview, or open in the browser — every single time. Activating the link
is already a deliberate gesture, so the extra click bought nothing on the
one destination that can actually reach the port.

Loopback links now open straight in the integrated browser, and everything
else still goes straight to the system browser. The preview chrome already
carries an open-in-system-browser button, so the way out survives, and a
failed open still falls back to the system browser.

This drops the menu, and with it TerminalLinkContextMenuShowError and the
localApi and position arguments the menu needed.
@incognitojam
incognitojam force-pushed the t3code/terminal-loopback-links branch from 188915c to 4cc31f3 Compare August 15, 2026 22:36
@incognitojam
incognitojam merged commit c787841 into main Aug 15, 2026
8 of 9 checks passed
@incognitojam
incognitojam deleted the t3code/terminal-loopback-links branch August 15, 2026 22:53
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 18, 2026
> [!NOTE]
> TL;DR: Cmd-clicking an `http://localhost:5173` link in the terminal
now opens the integrated browser directly instead of popping a two-item
chooser first. Non-loopback links are unchanged. Follow-up to #153, but
independent of it.

## The problem

Activating a loopback link in the terminal showed a menu at the cursor —
"Open in preview" / "Open in browser" — on every single click.
Activation is already a deliberate modifier gesture (cmd-click on macOS,
ctrl-click elsewhere), so the chooser added a second click to every
visit to a dev server you are iterating on, for a decision that is
nearly always the same one.

Non-loopback URLs never showed the menu; they already went straight to
the system browser. So the menu was the only place in the app where
following a link asked a question first.

## What changed

`openTerminalLinkInPreview` opens loopback links in the integrated
browser and hands everything else to the system browser, with no menu in
between. That deletes the menu plumbing:
`TerminalLinkContextMenuShowError`, and the `localApi` and `position`
arguments that only existed to position and show it — 107 lines out, 63
in.

The loopback test, the failure fallback, the interrupt handling, and the
origin-only error logging (so a link carrying a token in its query is
not logged) are all unchanged.

## Reverse state

The way back out is the integrated browser's own open-in-system-browser
button in `PreviewChromeRow`, which is one click and already there. I
deliberately did not invent a modifier for "system browser instead":
cmd/ctrl is already spent on activation itself, and a shift variant
would be undiscoverable. If it turns out people want the choice back, a
setting is the honest shape for it, not a menu on every click.

## Relationship to #153

Same reasoning applied to a different surface, and the two together make
the rule uniform: a loopback link opens in the integrated browser
because it is the only browser that can reach the environment's ports;
every other host opens in the system browser, where the reader is signed
in.

They touch disjoint files and can land in either order, so this is a
separate PR rather than a stacked one.

## Surfaces

- **Desktop:** new behavior.
- **Web in a plain browser:** unchanged. `isPreviewSupportedInRuntime()`
is false, so links fall through to the system browser exactly as before.
- **Mobile:** no terminal drawer, nothing to change.

## Verification

- `vp test run
apps/web/src/components/preview/openTerminalLinkInPreview.test.ts`
- `vp run @t3tools/web#typecheck`
- `vp check` on the three changed files

## Checklist

- [x] This PR is focused on removing one chooser from one gesture
- [x] I explained what changed and why
- [ ] No before/after image: the terminal link looks identical, and the
visible difference is the absence of a menu. Verified manually.
- [x] No video is needed because this change adds no motion or timing
behavior

---
Written by an agent (Claude Code, claude-opus-5).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant