opencode icon indicating copy to clipboard operation
opencode copied to clipboard

feat(desktop): open external links in system browser instead of webview

Open tang-vu opened this issue 1 day ago • 2 comments

Summary

Fixes #8361

This PR fixes the issue where clicking links in AI responses navigates inside the Tauri webview instead of opening in the system browser.

What makes this PR different from #8520 and #7360:

  • User toggle setting - Users can choose between external browser or in-app navigation
  • Command palette integration - Quick toggle via Mod+Shift+P
  • UI toggle button - Visible in sidebar footer (desktop only)
  • Persisted preference - Setting survives app restarts

Changes

  • Global click handler: Intercepts all <a> tag clicks with http:// or https:// URLs and opens them via shellOpen() in the system browser
  • User setting: Added links.openExternally to Layout context (persisted) so users can toggle between external browser and in-app navigation
  • Command palette: Added "Open links in browser/app" command for quick toggling
  • UI toggle: Added a toggle button in the sidebar footer (only visible on desktop)

Problem

In Tauri webview, target="_blank" on <a> tags does NOT automatically open links in the system browser. When users click links from:

  • Markdown rendered AI responses
  • Native <a> tags (like the feedback button)

...the webview navigates to that URL, and users get "stuck" with no obvious way to return.

Solution

Added a global click handler that:

  1. Intercepts clicks on <a> tags with external URLs
  2. Checks user preference (window.__OPENCODE__.openLinksExternally)
  3. If enabled (default: true), prevents default navigation and opens via shellOpen()

Testing

  1. Run bun dev in packages/opencode
  2. Open desktop app
  3. Ask the AI to respond with a link (e.g., "give me a link to github")
  4. Click the link → should open in system browser
  5. Toggle the setting in sidebar → links should now navigate in-app

Files Changed

File Change
packages/desktop/src/index.tsx Global click handler
packages/app/src/context/layout.tsx Persisted setting + sync to window.__OPENCODE__
packages/app/src/app.tsx Type definition for window.__OPENCODE__
packages/app/src/pages/layout.tsx Command palette + UI toggle button

Default Behavior

Opens links in external browser (most users expect this behavior)

Users who prefer in-app browsing can toggle the setting.


Note: This PR is aware of #8520 and #7360 which address the same core issue. This PR adds additional user-facing features (toggle setting, command palette, UI button) that those PRs don't include. Happy to collaborate or consolidate if needed!

tang-vu avatar Jan 14 '26 18:01 tang-vu