From 949539a2c7a812cd336741deb3195df8231ceb67 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 17:20:27 -0700 Subject: [PATCH] feat(landing): add Share chip to integration and model pages - add a Share chip (copy link / X / LinkedIn) to integration and model detail pages, matching the bordered secondary-pill chip already used for View docs / All {provider} models - rework ShareButton to render as a Chip everywhere (blog, library, integrations, models) instead of a bespoke muted-text trigger, and switch its copy-link state to the shared useCopyToClipboard hook --- .../components/share-button/share-button.tsx | 37 ++++++++----------- .../integrations/(shell)/[slug]/page.tsx | 2 + .../(shell)/[provider]/[model]/page.tsx | 2 + 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/apps/sim/app/(landing)/components/share-button/share-button.tsx b/apps/sim/app/(landing)/components/share-button/share-button.tsx index 57c5ad98357..8d0bb6dc095 100644 --- a/apps/sim/app/(landing)/components/share-button/share-button.tsx +++ b/apps/sim/app/(landing)/components/share-button/share-button.tsx @@ -1,7 +1,14 @@ 'use client' -import { useState } from 'react' -import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@sim/emcn' +import { + Chip, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, + TRIGGER_BORDER_CLASS, + useCopyToClipboard, +} from '@sim/emcn' import { Duplicate } from '@sim/emcn/icons' import { Share2 } from 'lucide-react' import { LinkedInIcon, xIcon as XIcon } from '@/components/icons' @@ -11,18 +18,9 @@ interface ShareButtonProps { title: string } +/** Bordered `Chip` trigger with a copy-link / X / LinkedIn share menu — the one Share control used across blog, library, integration, and model pages. */ export function ShareButton({ url, title }: ShareButtonProps) { - const [copied, setCopied] = useState(false) - - const handleCopyLink = async () => { - try { - await navigator.clipboard.writeText(url) - setCopied(true) - setTimeout(() => setCopied(false), 1500) - } catch { - /* clipboard unavailable */ - } - } + const { copied, copy } = useCopyToClipboard({ resetMs: 1500 }) const handleShareTwitter = () => { const tweetUrl = `https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}&text=${encodeURIComponent(title)}` @@ -37,17 +35,12 @@ export function ShareButton({ url, title }: ShareButtonProps) { return ( - + + Share + - + copy(url)}> {copied ? 'Copied!' : 'Copy link'} diff --git a/apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx b/apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx index d0cdedffa71..c8f51ea1ce1 100644 --- a/apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx +++ b/apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx @@ -17,6 +17,7 @@ import { import { BackLink } from '@/app/(landing)/components' import { JsonLd } from '@/app/(landing)/components/json-ld' import { LandingFAQ } from '@/app/(landing)/components/landing-faq' +import { ShareButton } from '@/app/(landing)/components/share-button' import { IntegrationCtaButton } from '@/app/(landing)/integrations/(shell)/[slug]/components/integration-cta-button' import { TemplateCardButton } from '@/app/(landing)/integrations/(shell)/[slug]/components/template-card-button' import { IntegrationIcon } from '@/app/(landing)/integrations/components/integration-icon' @@ -494,6 +495,7 @@ export default async function IntegrationPage({ params }: { params: Promise<{ sl > View docs +

diff --git a/apps/sim/app/(landing)/models/(shell)/[provider]/[model]/page.tsx b/apps/sim/app/(landing)/models/(shell)/[provider]/[model]/page.tsx index 76c7a06e342..3c59189fc90 100644 --- a/apps/sim/app/(landing)/models/(shell)/[provider]/[model]/page.tsx +++ b/apps/sim/app/(landing)/models/(shell)/[provider]/[model]/page.tsx @@ -5,6 +5,7 @@ import { SITE_URL } from '@/lib/core/utils/urls' import { BackLink } from '@/app/(landing)/components' import { JsonLd } from '@/app/(landing)/components/json-ld' import { LandingFAQ } from '@/app/(landing)/components/landing-faq' +import { ShareButton } from '@/app/(landing)/components/share-button' import { FeaturedModelCard, ProviderIcon } from '@/app/(landing)/models/components/model-primitives' import { ALL_CATALOG_MODELS, @@ -181,6 +182,7 @@ export default async function ModelPage({ All {provider.name} models +