From 10d2a59468909987e2544ff8f40996520b1af13f Mon Sep 17 00:00:00 2001 From: Shannon Anahata Date: Tue, 9 Jun 2026 14:22:48 -0700 Subject: [PATCH 1/4] feat: add inline 'Copy Prompt' button to platform links on getting-started pages Add an optional `skill` prop to `LinkWithPlatformIcon` that renders an inline copy-prompt button next to platform links that have agent-assisted setup skills. Clicking the button copies the agent setup prompt to the clipboard (e.g., `Use curl to download, read and follow: https://skills.sentry.dev/{skill}/SKILL.md`). Changes: - Extract shared prompt-building utilities into `agentSkillsCallout/shared.ts` - Create `CopyPromptButton` client component with Radix tooltip, Plausible analytics, and Sentry metrics tracking - Update `LinkWithPlatformIcon` to accept optional `skill` prop - Add `skill` props to 20 platform links on the logs getting-started page --- .../explore/logs/getting-started/index.mdx | 21 ++- src/components/agentSkillsCallout/index.tsx | 30 +--- src/components/agentSkillsCallout/shared.ts | 33 +++++ src/components/copyPromptButton/index.tsx | 132 ++++++++++++++++++ .../copyPromptButton/style.module.scss | 70 ++++++++++ src/components/linkWithPlatformIcon.tsx | 6 +- 6 files changed, 260 insertions(+), 32 deletions(-) create mode 100644 src/components/agentSkillsCallout/shared.ts create mode 100644 src/components/copyPromptButton/index.tsx create mode 100644 src/components/copyPromptButton/style.module.scss diff --git a/docs/product/explore/logs/getting-started/index.mdx b/docs/product/explore/logs/getting-started/index.mdx index a743b1fe17cd0..8dc95e4e69dc8 100644 --- a/docs/product/explore/logs/getting-started/index.mdx +++ b/docs/product/explore/logs/getting-started/index.mdx @@ -14,6 +14,7 @@ To set up Sentry Logs, use the links below for supported SDKs. After it's been s platform="javascript.browser" label="Browser JavaScript" url="/platforms/javascript/logs/" + skill="sentry-browser-sdk" /> - - - - - - - - - - - - - ### PHP -- +- - ### Ruby @@ -240,6 +255,7 @@ To set up Sentry Logs, use the links below for supported SDKs. After it's been s platform="ruby" label="Ruby" url="/platforms/ruby/logs/" + skill="sentry-ruby-sdk" /> - +- ### Rust @@ -265,6 +281,7 @@ To set up Sentry Logs, use the links below for supported SDKs. After it's been s platform="dotnet" label=".NET" url="/platforms/dotnet/logs/" + skill="sentry-dotnet-sdk" /> - ({ + borderRadius: '4px', + padding: '8px 12px', + fontSize: '12px', + lineHeight: 1.2, + textAlign: 'center' as const, + color: isDark ? 'var(--foreground)' : 'var(--gray-11)', + backgroundColor: isDark ? 'var(--gray-4)' : 'white', + boxShadow: '0px 4px 16px 0px rgba(31, 22, 51, 0.1)', + zIndex: 9999, + position: 'relative' as const, + pointerEvents: 'none' as const, + userSelect: 'none' as const, + whiteSpace: 'nowrap' as const, + animationDuration: '100ms', + animationTimingFunction: 'ease-in', + }), + [isDark] + ); + + const tooltipArrowStyle: React.CSSProperties = useMemo( + () => ({ + fill: isDark ? 'var(--gray-4)' : 'white', + }), + [isDark] + ); + + const copyPrompt = useCallback( + async (event: React.MouseEvent) => { + event.stopPropagation(); + event.preventDefault(); + + emit('Copy AI Prompt', { + props: {page: window.location.pathname, title: 'Inline Platform Link'}, + }); + + try { + setCopied(false); + await navigator.clipboard.writeText(prompt); + setCopied(true); + DocMetrics.copyAIPrompt(window.location.pathname, skill, true); + setTimeout(() => setCopied(false), 1500); + } catch (error) { + Sentry.captureException(error); + DocMetrics.copyAIPrompt(window.location.pathname, skill, false); + setCopied(false); + } + }, + [prompt, emit, skill] + ); + + return ( + + | + + + + + + {!copied && ( + + + + Copy setup prompt for AI agents + + + + + )} + + + + ); +} + +function CopyIcon() { + return ( + + + + + ); +} diff --git a/src/components/copyPromptButton/style.module.scss b/src/components/copyPromptButton/style.module.scss new file mode 100644 index 0000000000000..4bc6f92171583 --- /dev/null +++ b/src/components/copyPromptButton/style.module.scss @@ -0,0 +1,70 @@ +.wrapper { + display: inline-flex; + align-items: center; + margin-left: 0.4rem; + vertical-align: middle; + + @media (max-width: 768px) { + display: none; + } +} + +.divider { + color: var(--gray-200); + font-size: 0.85rem; + margin-right: 0.4rem; + user-select: none; +} + +:global(.dark) .divider { + color: var(--gray-600); +} + +.button { + display: inline-flex; + align-items: center; + gap: 0.3rem; + padding: 0.15rem 0.5rem; + border: 1px solid color-mix(in srgb, var(--accent-purple), transparent 60%); + border-radius: 4px; + background: color-mix(in srgb, var(--accent-purple), transparent 92%); + color: var(--accent-purple); + font-size: 0.72rem; + font-weight: 500; + white-space: nowrap; + cursor: pointer; + transition: + background-color 150ms, + border-color 150ms; + line-height: 1.4; + + &:hover { + background: color-mix(in srgb, var(--accent-purple), transparent 82%); + border-color: color-mix(in srgb, var(--accent-purple), transparent 40%); + } + + &:active { + background: color-mix(in srgb, var(--accent-purple), transparent 72%); + } +} + +:global(.dark) .button { + background: color-mix(in srgb, var(--accent-purple), transparent 85%); + border-color: color-mix(in srgb, var(--accent-purple), transparent 50%); + color: var(--accent-purple-light, var(--accent-purple)); + + &:hover { + background: color-mix(in srgb, var(--accent-purple), transparent 75%); + border-color: color-mix(in srgb, var(--accent-purple), transparent 30%); + } + + &:active { + background: color-mix(in srgb, var(--accent-purple), transparent 65%); + } +} + +.label { + letter-spacing: 0.01em; +} + + diff --git a/src/components/linkWithPlatformIcon.tsx b/src/components/linkWithPlatformIcon.tsx index 84b22326de675..17ae9d8b53e1a 100644 --- a/src/components/linkWithPlatformIcon.tsx +++ b/src/components/linkWithPlatformIcon.tsx @@ -1,13 +1,16 @@ +import {CopyPromptButton} from './copyPromptButton'; import {PlatformIcon} from './platformIcon'; import {SmartLink} from './smartLink'; type Props = { label?: string; platform?: string; + /** Agent skill name, e.g. "sentry-react-sdk". When provided, renders an inline "Agent Setup" copy-prompt button. */ + skill?: string; url?: string; }; -export function LinkWithPlatformIcon({platform, label, url}: Props) { +export function LinkWithPlatformIcon({platform, label, url, skill}: Props) { if (!platform) { return null; } @@ -27,6 +30,7 @@ export function LinkWithPlatformIcon({platform, label, url}: Props) { /> {label ?? platform} + {skill && } ); } From 8066ce832834ccf2fa527d598d57a8b797590e65 Mon Sep 17 00:00:00 2001 From: Shannon Anahata Date: Tue, 9 Jun 2026 14:32:55 -0700 Subject: [PATCH 2/4] feat: add skill props to remaining frameworks on logs, metrics, and profiling pages Add copy-prompt buttons to additional platform links: - Logs page: add sentry-node-sdk for server-side JS frameworks (Express, Fastify, Hapi, Koa, Connect, Hono, Bun, AWS Lambda, GCP Functions, Azure Functions) and sentry-browser-sdk for browser-only frameworks (Angular, Ember, Gatsby, Solid, Vue, Wasm) - Metrics page: add skill props to all 47 applicable platform links across JS, Python, Ruby, Go, PHP, .NET, Mobile, and Elixir sections - Profiling page: add skill props to 11 applicable platform links across Continuous, UI, and Transaction-based profiling sections Frameworks with ambiguous SDK mappings (Astro, Nuxt, Remix, SolidStart, Electron, Capacitor) are intentionally left without a skill prop until framework-specific skills are created. --- .../explore/logs/getting-started/index.mdx | 16 +++++++ .../explore/metrics/getting-started/index.mdx | 47 +++++++++++++++++++ .../explore/profiling/getting-started.mdx | 11 +++++ 3 files changed, 74 insertions(+) diff --git a/docs/product/explore/logs/getting-started/index.mdx b/docs/product/explore/logs/getting-started/index.mdx index 8dc95e4e69dc8..163c9bdacff3b 100644 --- a/docs/product/explore/logs/getting-started/index.mdx +++ b/docs/product/explore/logs/getting-started/index.mdx @@ -20,6 +20,7 @@ To set up Sentry Logs, use the links below for supported SDKs. After it's been s platform="javascript.angular" label="Angular" url="/platforms/javascript/guides/angular/logs/" + skill="sentry-browser-sdk" /> - - - - - - - - - - - - - - - ### Java diff --git a/docs/product/explore/metrics/getting-started/index.mdx b/docs/product/explore/metrics/getting-started/index.mdx index c15e6d8c0bef2..7e115859bd11c 100644 --- a/docs/product/explore/metrics/getting-started/index.mdx +++ b/docs/product/explore/metrics/getting-started/index.mdx @@ -14,11 +14,13 @@ To set up Sentry's Application Metrics, use the links below for supported SDKs. platform="javascript.browser" label="Browser JavaScript" url="/platforms/javascript/metrics/" + skill="sentry-browser-sdk" /> - - - - - - - - - - - - - - - - - - - - - - - - - ### Java @@ -190,6 +216,7 @@ To set up Sentry's Application Metrics, use the links below for supported SDKs. platform="elixir" label="Elixir" url="/platforms/elixir/metrics/" + skill="sentry-elixir-sdk" /> ### Mobile @@ -198,41 +225,49 @@ To set up Sentry's Application Metrics, use the links below for supported SDKs. platform="android" label="Android" url="/platforms/android/metrics/" + skill="sentry-android-sdk" /> - - - - - - - ### Python @@ -241,41 +276,49 @@ To set up Sentry's Application Metrics, use the links below for supported SDKs. platform="python" label="Python" url="/platforms/python/metrics/" + skill="sentry-python-sdk" /> - - - - - - - ### PHP @@ -284,6 +327,7 @@ To set up Sentry's Application Metrics, use the links below for supported SDKs. platform="php" label="PHP" url="/platforms/php/metrics/" + skill="sentry-php-sdk" /> - ### Go @@ -310,6 +355,7 @@ To set up Sentry's Application Metrics, use the links below for supported SDKs. platform="go" label="Go" url="/platforms/go/metrics/" + skill="sentry-go-sdk" /> ### .NET @@ -318,6 +364,7 @@ To set up Sentry's Application Metrics, use the links below for supported SDKs. platform="dotnet" label=".NET" url="/platforms/dotnet/metrics/" + skill="sentry-dotnet-sdk" /> - - ### UI Profiling @@ -45,16 +47,19 @@ UI Profiling can be used both independently and as a complement to the tracing p platform="apple" label="iOS & macOS (since version 8.49.0)" url="/platforms/apple/profiling/" + skill="sentry-cocoa-sdk" /> - - - - - #### Standalone and server apps @@ -96,14 +104,17 @@ Transaction-based Profiling requires Sentry's tracing product being enabled befo platform="php" label="PHP" url="/platforms/php/profiling/" + skill="sentry-php-sdk" /> - - From 82ac8cc92f95d63b451d624b3ca8d10d1bc9ece5 Mon Sep 17 00:00:00 2001 From: Shannon Anahata Date: Tue, 9 Jun 2026 14:40:45 -0700 Subject: [PATCH 3/4] feat: add skill props to all remaining sub-frameworks Every sub-framework now inherits its parent platform's skill: - JS full-stack frameworks (Astro, Nuxt, Remix, SolidStart) -> sentry-node-sdk - Electron -> sentry-node-sdk - Capacitor -> sentry-browser-sdk - PHP sub-frameworks (Symfony, Laravel) -> sentry-php-sdk - Ruby sub-frameworks (Rails) -> sentry-ruby-sdk - All .NET sub-frameworks -> sentry-dotnet-sdk Only entries without an available skill remain: Java and Gaming. --- .../explore/logs/getting-started/index.mdx | 13 ++++++++++ .../explore/metrics/getting-started/index.mdx | 24 +++++++++++++++++++ .../explore/profiling/getting-started.mdx | 1 + 3 files changed, 38 insertions(+) diff --git a/docs/product/explore/logs/getting-started/index.mdx b/docs/product/explore/logs/getting-started/index.mdx index 163c9bdacff3b..10d82fbc7a1fd 100644 --- a/docs/product/explore/logs/getting-started/index.mdx +++ b/docs/product/explore/logs/getting-started/index.mdx @@ -26,6 +26,7 @@ To set up Sentry Logs, use the links below for supported SDKs. After it's been s platform="javascript.astro" label="Astro" url="/platforms/javascript/guides/astro/logs/" + skill="sentry-node-sdk" /> - - - - - - - ### Python @@ -277,6 +285,7 @@ To set up Sentry Logs, use the links below for supported SDKs. After it's been s platform="ruby.rails" label="Rails" url="/platforms/ruby/guides/rails/logs/" + skill="sentry-ruby-sdk" /> ### Go @@ -303,21 +312,25 @@ To set up Sentry Logs, use the links below for supported SDKs. After it's been s platform="dotnet.aspnetcore" label="ASP.NET Core" url="/platforms/dotnet/guides/aspnetcore/logs/" + skill="sentry-dotnet-sdk" /> - - - ### Native diff --git a/docs/product/explore/metrics/getting-started/index.mdx b/docs/product/explore/metrics/getting-started/index.mdx index 7e115859bd11c..49352cc718de3 100644 --- a/docs/product/explore/metrics/getting-started/index.mdx +++ b/docs/product/explore/metrics/getting-started/index.mdx @@ -26,6 +26,7 @@ To set up Sentry's Application Metrics, use the links below for supported SDKs. platform="javascript.astro" label="Astro" url="/platforms/javascript/guides/astro/metrics/" + skill="sentry-node-sdk" /> - - - - - - ### Ruby @@ -370,86 +377,103 @@ To set up Sentry's Application Metrics, use the links below for supported SDKs. platform="dotnet.android" label=".NET for Android" url="/platforms/dotnet/guides/android/metrics/" + skill="sentry-dotnet-sdk" /> - - - - - - - - - - - - - - - - ### Native diff --git a/docs/product/explore/profiling/getting-started.mdx b/docs/product/explore/profiling/getting-started.mdx index 7649ccc35a802..847f18be738bf 100644 --- a/docs/product/explore/profiling/getting-started.mdx +++ b/docs/product/explore/profiling/getting-started.mdx @@ -65,6 +65,7 @@ UI Profiling can be used both independently and as a complement to the tracing p platform="javascript.electron" label="Electron (since version 7.4.0)" url="/platforms/javascript/guides/electron/profiling/" + skill="sentry-node-sdk" /> ### Transaction-based Profiling From 927aec421420c2a4c861c613e61999593c48d2ed Mon Sep 17 00:00:00 2001 From: Shannon Anahata Date: Wed, 10 Jun 2026 10:40:39 -0700 Subject: [PATCH 4/4] feat: add source attribute to copy_ai_prompt metric Add a `source` attribute to the `docs.copy_ai_prompt` Sentry metric to distinguish between the full AgentSkillsCallout banner ('callout') and the new inline platform link buttons ('inline_link'). Existing callers default to 'callout' so no changes are needed in AgentSkillsCallout. --- src/components/copyPromptButton/index.tsx | 4 ++-- src/metrics.ts | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/copyPromptButton/index.tsx b/src/components/copyPromptButton/index.tsx index e51a487337b78..b010c98c41971 100644 --- a/src/components/copyPromptButton/index.tsx +++ b/src/components/copyPromptButton/index.tsx @@ -70,11 +70,11 @@ export function CopyPromptButton({skill}: Props) { setCopied(false); await navigator.clipboard.writeText(prompt); setCopied(true); - DocMetrics.copyAIPrompt(window.location.pathname, skill, true); + DocMetrics.copyAIPrompt(window.location.pathname, skill, true, 'inline_link'); setTimeout(() => setCopied(false), 1500); } catch (error) { Sentry.captureException(error); - DocMetrics.copyAIPrompt(window.location.pathname, skill, false); + DocMetrics.copyAIPrompt(window.location.pathname, skill, false, 'inline_link'); setCopied(false); } }, diff --git a/src/metrics.ts b/src/metrics.ts index d4b34347e6c1d..8e0343e3f7064 100644 --- a/src/metrics.ts +++ b/src/metrics.ts @@ -166,13 +166,20 @@ export const DocMetrics = { * @param pathname - Page where the prompt was copied * @param skill - Skill name if present (e.g., "sentry-nextjs-sdk") * @param success - Whether the clipboard copy succeeded + * @param source - Where the copy was triggered from ('callout' for the full banner, 'inline_link' for platform list buttons) */ - copyAIPrompt: (pathname: string, skill: string | undefined, success: boolean) => { + copyAIPrompt: ( + pathname: string, + skill: string | undefined, + success: boolean, + source: 'callout' | 'inline_link' = 'callout' + ) => { Sentry.metrics.count('docs.copy_ai_prompt', 1, { attributes: { page_path: pathname.split('/').slice(0, 3).join('/'), // First 3 segments skill: skill || 'generic', success, + source, }, }); },