From 81db565b9c0c4b30623d8e07191ffdbf23f3b2a3 Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Fri, 31 Jul 2026 04:50:31 +0200 Subject: [PATCH] feat(client): platform-native map links on place results Place rows were the only vertical without a destination. Each row now links out to the user's native maps app: Apple devices (detected via the existing isMacPlatform check) get maps.apple.com with the query and coordinates, everything else gets a Google Maps search link. Both are keyless https links that degrade to a web map, so a misdetected platform still lands somewhere useful. Rows pick up the same hover treatment as the other linked results. --- .../Content/__tests__/WebSearch.test.tsx | 5 ++ .../Chat/Messages/Content/verticals.tsx | 59 +++++++++++++------ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/client/src/components/Chat/Messages/Content/__tests__/WebSearch.test.tsx b/client/src/components/Chat/Messages/Content/__tests__/WebSearch.test.tsx index fb777ea849..1ebc4cc1ff 100644 --- a/client/src/components/Chat/Messages/Content/__tests__/WebSearch.test.tsx +++ b/client/src/components/Chat/Messages/Content/__tests__/WebSearch.test.tsx @@ -410,6 +410,11 @@ describe('WebSearch', () => { expect(screen.getByText('4.7')).toBeInTheDocument(); expect(screen.getByText('Blue Bottle Coffee')).toBeInTheDocument(); + const placeLink = screen.getByText('Blue Bottle Coffee').closest('a'); + expect(placeLink?.getAttribute('href')).toContain('google.com/maps'); + expect(placeLink?.getAttribute('href')).toContain( + encodeURIComponent('Blue Bottle Coffee, 300 S Broadway'), + ); expect(screen.getByText('Coffee shop \u00b7 300 S Broadway')).toBeInTheDocument(); expect(screen.getByText('4.6')).toBeInTheDocument(); expect(screen.getByText('(812)')).toBeInTheDocument(); diff --git a/client/src/components/Chat/Messages/Content/verticals.tsx b/client/src/components/Chat/Messages/Content/verticals.tsx index e3b841179e..4d04f4d067 100644 --- a/client/src/components/Chat/Messages/Content/verticals.tsx +++ b/client/src/components/Chat/Messages/Content/verticals.tsx @@ -6,12 +6,33 @@ import type { PlaceResult, ShoppingResult, } from 'librechat-data-provider'; +import { isMacPlatform } from '~/utils/shortcuts'; import { useLocalize } from '~/hooks'; import { cn } from '~/utils'; const MAX_VERTICAL_ITEMS = 8; const MAX_PLACES = 5; +/** Platform-native map link: Apple devices open Apple Maps, everything else + * Google Maps. Both are keyless https links that fall back to a web map when + * the native app is unavailable, so a misdetected platform still works. */ +export function mapLink(place: PlaceResult): string { + const query = [place.name, place.address].filter(Boolean).join(', '); + const coords = + place.latitude != null && place.longitude != null ? `${place.latitude},${place.longitude}` : ''; + if (isMacPlatform) { + const params = new URLSearchParams(); + if (query) { + params.set('q', query); + } + if (coords) { + params.set('ll', coords); + } + return `https://maps.apple.com/?${params.toString()}`; + } + return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(query || coords)}`; +} + export interface SearchVerticalData { images: ImageResult[]; shopping: ShoppingResult[]; @@ -135,25 +156,29 @@ function PlaceList({ places, label }: { places: PlaceResult[]; label: string }) {places.slice(0, MAX_PLACES).map((place, i) => (