fix(canvas): navigate share links in-app instead of via the browser#3582
Conversation
Clicking a canvas/channel share link in a channel thread bounced out to the browser (PostHog Cloud interstitial) which then deep-linked back into the app. The thread feed renders server-emitted announcement messages whose content embeds a portable https share link; those links were rendered as plain external anchors with no in-app interception. Add a client-side parser that recognizes our own share-link URLs (/code/canvas/... and /code/channel/...) and navigates via the in-app router, short-circuiting the browser round-trip. Wired into MentionText (thread + channel surfaces) and MarkdownRenderer (agent chat). External links are untouched. Generated-By: PostHog Code Task-Id: a3001315-524a-4902-b23c-5c6f5b010827
|
😎 Merged successfully - details. |
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
Move parseShareLink next to canvasShareUrl/channelShareUrl in posthogLinks.ts so the /code/canvas and /code/channel path shapes live in one place (the parser is the inverse of the builders). Derive the recognized-host set from REGION_LABELS instead of a hardcoded region list. shareLinks.ts is now just the navigation glue (navigateToShareTarget/handleShareLinkClick). Generated-By: PostHog Code Task-Id: a3001315-524a-4902-b23c-5c6f5b010827
Generated-By: PostHog Code Task-Id: a3001315-524a-4902-b23c-5c6f5b010827
Generated-By: PostHog Code Task-Id: a3001315-524a-4902-b23c-5c6f5b010827
Generated-By: PostHog Code Task-Id: a3001315-524a-4902-b23c-5c6f5b010827
There was a problem hiding this comment.
Clean, well-tested UI fix that adds in-app navigation for PostHog share links. The host-allowlist validation is conservative (only known PostHog regions), URL decoding is defensive, and the fallback to normal browser navigation for non-matching links is intact. No architecture violations, no data model or API contract changes.
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
packages/ui/src/utils/shareLinks.ts:30-34
**Modified Click Loses New Tab**
When a user Ctrl/Cmd-clicks or Shift-clicks a recognized share link, this path consumes the event and navigates the current app. Both callers render `target="_blank"`, so modified clicks should retain the native new-tab or new-window behavior instead of replacing the current view.
Reviews (1): Last reviewed commit: "refactor(canvas): match share links agai..." | Re-trigger Greptile |
| if (!href) return false; | ||
| const target = parseShareLink(href); | ||
| if (!target) return false; | ||
| event.preventDefault(); | ||
| navigateToShareTarget(target); |
There was a problem hiding this comment.
When a user Ctrl/Cmd-clicks or Shift-clicks a recognized share link, this path consumes the event and navigates the current app. Both callers render target="_blank", so modified clicks should retain the native new-tab or new-window behavior instead of replacing the current view.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/ui/src/utils/shareLinks.ts
Line: 30-34
Comment:
**Modified Click Loses New Tab**
When a user Ctrl/Cmd-clicks or Shift-clicks a recognized share link, this path consumes the event and navigates the current app. Both callers render `target="_blank"`, so modified clicks should retain the native new-tab or new-window behavior instead of replacing the current view.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
A Cmd/Ctrl/Shift/middle click on a share link is explicit intent to open it elsewhere; don't hijack it for in-app navigation. handleShareLinkClick now bails on modified clicks so the anchor's target="_blank" default runs. Generated-By: PostHog Code Task-Id: a3001315-524a-4902-b23c-5c6f5b010827
New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.
There was a problem hiding this comment.
Clean UI-only fix with comprehensive tests. The greptile bot's modified-click concern was resolved in a subsequent commit — the current diff shows isModifiedClick properly passes through meta/ctrl/shift/alt and middle-button clicks. Host allowlist is conservative and URL decoding is defensive.
Problem
Clicking a canvas link in a channel thread opened PostHog Cloud in the external browser, which then deep-linked back into PostHog Code — an unnecessary round-trip, since the user is already in the app.
Why: reported in-app annoyance — the click flashes out to the browser and back instead of just navigating. Confirmed live on latest
main(not a stale local version).Changes
The thread feed renders server-emitted announcement messages (e.g. "Name has been created") whose content embeds a portable https share link — deliberately portable so the same message works on web, Slack, and for users without the app. Those links were rendered as plain external anchors, so clicking one handed the URL to the OS browser → Cloud interstitial →
posthog-code://back into the app.Fix at the client render/click layer (leaving the portable stored content intact):
shareLinks.tsutil — parses our own share-link URLs (/code/canvas/<channelId>/<dashboardId>,/code/channel/<channelId>[/tasks/<taskId>]) on a known PostHog host and navigates via the existing in-app router (navigationBridge), cancelling the default open-in-browser.MentionText(thread sidebar + channel feed / activity / intro) andMarkdownRenderer(agent chat). Any link that isn't a recognized share link is untouched and still opens externally.Host matching covers all PostHog regions (not just the signed-in one), since the inbound deep-link handlers already navigate by id against the current session — so intercepting is strictly faster with the same destination.
How did you test this?
pnpm --filter @posthog/ui exec vitest run src/utils/shareLinks.test.ts src/features/canvas/components/MentionText.test.tsx→ 20 passed. Covers canvas / channel / channel+task parses, encoded ids, non-PostHog host + wrong-path + malformed rejection, and click interception (preventDefault + in-app navigate) vs. external links passing through.biome check) and no typecheck errors inpackages/ui/srcfor the changed files.@posthog/agentdist build).Automatic notifications
Created with PostHog Code