Skip to content

feat(chat): favicon external links with secure link-preview tooltips#5734

Merged
waleedlatif1 merged 6 commits into
stagingfrom
chat-external-link-favicons
Jul 17, 2026
Merged

feat(chat): favicon external links with secure link-preview tooltips#5734
waleedlatif1 merged 6 commits into
stagingfrom
chat-external-link-favicons

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • external http(s) links in chat responses now render with the site's favicon (Google s2 service, 2x fetched, 12px, optically aligned to cap height) + a quiet solid underline in --text-muted that darkens to --text-primary on hover — replaces the harsh dashed underline; mailto/anchor/relative links keep the old treatment
  • hovering a link shows an OG-metadata preview tooltip (title / description / site name) via a new contract-bound GET /api/link-preview route: session-gated, fetches through the existing SSRF toolkit (secureFetchWithValidation — DNS-pinned, private-IP blocked) with 5s timeout, 3-redirect cap, 256KB response cap, head-only OG parsing, and Redis caching (24h positive / 1h negative); any failure returns a null preview and the tooltip falls back to the URL
  • preview requests fire only on hover intent (Radix lazy-mounts tooltip content) through a new useLinkPreview React Query hook
  • consolidated the favicon URL into a shared faviconUrl() helper, now used by both chat and the tables URL cell (previously inline there)
  • bumped the api-validation route-count baseline 963→964 for the new route

Type of Change

  • New feature

Testing

Tested manually against the running app (favicon alignment across 10 sites, preview tooltips, 401 unauthenticated, bot-blocked-site fallback)

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 17, 2026 5:10pm

Request Review

@cursor

cursor Bot commented Jul 17, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Adds a user-triggered server URL-fetch proxy; risk is mitigated by session auth, rate limits, SSRF tooling, and https-only fetches, but outbound fetch endpoints warrant careful review.

Overview
Chat http(s) links now use a new ExternalLink treatment: site favicon (via shared faviconUrl()), muted underline that darkens on hover, and a tooltip with OG title/description/site name when available. mailto, relative, and anchor links keep simpler styling; workspace resource links are unchanged.

A contract-backed GET /api/link-preview proxies metadata fetches for authenticated users: per-user rate limiting, https-only server fetches through secureFetchWithValidation, bounded timeout/redirects/response size, cheerio OG/Twitter meta parsing, and Redis caching (24h hits / 1h misses). Failures return { preview: null } and the tooltip falls back to the raw URL. useLinkPreview loads previews when external links render (https only on the client).

Table URL cells now use the same faviconUrl() helper instead of an inline Google favicon URL. API validation baseline route count is 963 → 964.

Reviewed by Cursor Bugbot for commit 93eb14e. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds secure link previews and favicon styling for external links in chat. The main changes are:

  • Adds an authenticated and rate-limited link-preview API route.
  • Fetches metadata through the existing SSRF validation layer.
  • Caches preview results in Redis using hashed URL keys.
  • Adds a React Query hook and tooltip-based preview UI.
  • Shares favicon URL generation across chat and table cells.

Confidence Score: 5/5

The updated code appears safe to merge.

  • No new blocking issue met the requirements for this follow-up review.
  • The latest fixes cover the reported HTTP handling, cache-key exposure, request limiting, and URL logging paths.

Important Files Changed

Filename Overview
apps/sim/app/api/link-preview/route.ts Adds authenticated metadata fetching, response limits, rate limiting, URL-key hashing, and Redis caching.
apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/chat-content/external-link.tsx Adds favicon-enhanced external links with metadata tooltips.
apps/sim/hooks/queries/link-preview.ts Adds a contract-bound React Query hook for link previews.
apps/sim/lib/api/contracts/link-preview.ts Defines the validated request and response contract for link previews.

Reviews (6): Last reviewed commit: "improvement(chat): render mailto links a..." | Re-trigger Greptile

Comment thread apps/sim/app/api/link-preview/route.ts
Comment thread apps/sim/app/api/link-preview/route.ts Outdated
Comment thread apps/sim/app/api/link-preview/route.ts Outdated
Comment thread apps/sim/app/api/link-preview/route.ts
- allow http fetches to match advertised http(s) link support
- fix meta content regex to handle apostrophes and either quote delimiter
- hash Redis cache keys so sensitive URLs are not stored verbatim
- add per-user rate limit to the outbound-fetching route
- render siteName-only previews instead of falling back to the URL
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit bde6f31. Configure here.

Comment thread apps/sim/app/api/link-preview/route.ts Outdated
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 242ad88. Configure here.

…, cleanup pass

- fetch previews when links render (emcn tooltip shows instantly — hover prefetch had no delay to race); tooltip reads the warmed cache, eliminating the URL-then-preview flash
- parse OG metadata with cheerio (already used server-side) instead of hand-rolled regexes + entity decoding, fixing double-decode and quote-handling classes
- drop the no-longer-needed prefetch hook; remove dead side prop on Tooltip.Content
- extract ExternalLink to a sibling module per component-size guidelines; fix TSDoc placement
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/api/link-preview/route.ts Outdated
Comment thread apps/sim/app/api/link-preview/route.ts Outdated
- drop allowHttp: plain-http fetches would reach the URL validator's self-host loopback exception; previews are now explicitly https-only on both server (early null) and client (query never fires for http)
- parse the full capped document instead of truncating at the first <body> substring, which could match inside head scripts/comments and drop metadata
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 3eadb90. Configure here.

@waleedlatif1
waleedlatif1 merged commit 7e6aeb2 into staging Jul 17, 2026
13 checks passed
@waleedlatif1
waleedlatif1 deleted the chat-external-link-favicons branch July 17, 2026 17:10
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 93eb14e. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant